GitHub Repository The Rmarkdown file can be downloaded from the Code drop down menu (top right).

This supplementary file contains the R workflow for processing and analysing the raw data, and creating figures for the manuscript titled “Global vulnerability of anurans to drought and warming”.

Abbreviations

  • AI: Aridity Index
  • EWL: Evaporative water loss
  • IUCN: International Union for Conservation of Nature
  • PDSI: Palmer Drought Severity Index
  • PRISMA: Preferred Reporting Items for Systematic Reviews and Meta-Analyses
  • RH: Relative humidity
  • SPP: Shared Socioeconomic Pathway
  • WU: water uptake

Spatial risk

Descriptors

The following series of code is used to estimate the risk of extant anurans to increasing aridity (Aridity Index; AI) and drought (Palmer Drought Severity Index; PDSI). The AI was categorised to five categories and The AI was categorised to five categories (Humid, Dry sub-humid, Semi-arid, Arid, and Hyper-arid) and the PDSI was categorised to seven categories (Extremely moist, Very moist, Moderate moist, Normal, Moderate drought, Severe drought, Extreme drought) based on descriptions from Budyko (1961) and Palmer (1965), respectively (Table S1).

Generalised ecological types or ‘ecotype’ were classified based on descriptions from Moen and Wiens (2017) focusing on adult behaviour and microhabitat preferences outside the breeding season given that many anurans breed in water but are not adapted to live in water all year (Table S2).

Table S1

Table S1 Aridity index (Budyko, 1961) and the Palmer Drought Severity Index (Palmer, 1965) categorised.

Aridity index (AI) AI value Palmer Drought Severity Index (PDSI) PDSI Value
Humid ≥ 0.65 Extremely moist ≥ 4
Dry sub-humid 0.50 – ≤ 0.65 Very moist 3 – ≤ 4
Semi-arid 0.20 – ≤ 0.50 Moderate moist 2 – ≤ 3
Arid 0.05 – ≤ 0.20 Normal -2 – ≤ 2
Hyper-arid < 0.05 Moderate drought -3 – ≤ -2
Severe drought -4 – ≤ -3
Extreme drought < -4

Table S2

Table S2 Microhabitat preference or ecotype (Moen and Wiens, 2017).

Ecotype Description
Aquatic Almost always in water.
Arboreal Ability to climb vegetation and spends a substantial amount of time above ground (e.g. forests, on top of vegetations in wetlands).
Semi-aquatic Stay near water bodies, usually permanent water (e.g. ground-level wetlands). Often observed in water and nearby vegetation.
Ground-dwelling Terrestrial only, not always near water bodies, however always in a moist environment (e.g. forest leaf litter, moist soils, scrublands, grassland). Sometimes above ground and sometimes semi-fossorial. Can be classified as broad.
Fossorial The non-breeding season is spent underground in burrows. Capable of burrowing and aestivating.
Stream-dwelling Restricted to near fast-flowing streams usually on rocks or vegetation near streams.

Species richness

Anuran (frogs and toads) distribution shape files were obtained from the International Union for Conservation of Nature’s Red List of Threatened Species (IUCN Red List; extracted on 11/01/2021). Species richness was defined as the sum of species in each grid cell (0.5°), based on the geographic range, and was calculated using the rasterizeIUCN and calcSR function from the from the rasterSp package. Ecotype-specific species richness was also calculated.

filedir <- "rasterSp/"

# Clean raw data
frog_dat <- read.csv(file.path(data_path, "anuran_species_list.csv")) %>%
    dplyr::select(genus:strategy, SVL_cm:binomial_tree_phylo) %>%
    dplyr::mutate(lnSVL = log(SVL_cm), lnMass = log(mass_g), lnArea = log(shape_area),
        IUCN = factor(IUCN, levels = c("Least Concern", "Near Threatened", "Vulnerable",
            "Endangered", "Critically Endangered", "Extinct")), order_name = factor(order_name),
        family_name = factor(family_name), ecotype = factor(ecotype)) %>%
    dplyr::filter(order_name == "ANURA" & ecotype != "" & IUCN != "" & IUCN != "Extinct") %>%
    droplevels()

# Convert shape files into rasters and save to file once (downloaded shape
# files 08/01/2020) only extracted distribution of native range anuran_rast <-
# rasterizeIUCN(dsn = paste0(filedir, 'ANURA/ANURA.shp'), resolution = 0.5,
# seasonal = c(1, 2), origin = 1, presence = c(1,2), save = TRUE, path =
# paste0(rasterSp_path))

# Calculate anuran richness and by ecotype The calcSR function uses a stepwise
# procedure to calculate the sum of species for each grid cell.
anuran_sr <- rasterSp::calcSR(species_names = frog_dat$binomial_IUCN, path = paste0(rasterSp_path))
aquatic_sr <- rasterSp::calcSR(species_names = frog_dat[frog_dat$ecotype == "Aquatic",
    "binomial_IUCN"], path = paste0(rasterSp_path))
arboreal_sr <- rasterSp::calcSR(species_names = frog_dat[frog_dat$ecotype == "Arboreal",
    "binomial_IUCN"], path = paste0(rasterSp_path))
fossorial_sr <- rasterSp::calcSR(species_names = frog_dat[frog_dat$ecotype == "Fossorial",
    "binomial_IUCN"], path = paste0(rasterSp_path))
ground_sr <- rasterSp::calcSR(species_names = frog_dat[frog_dat$ecotype == "Ground-dwelling",
    "binomial_IUCN"], path = paste0(rasterSp_path))
semi_aq_sr <- rasterSp::calcSR(species_names = frog_dat[frog_dat$ecotype == "Semi-aquatic",
    "binomial_IUCN"], path = paste0(rasterSp_path))
stream_sr <- rasterSp::calcSR(species_names = frog_dat[frog_dat$ecotype == "Stream-dwelling",
    "binomial_IUCN"], path = paste0(rasterSp_path))

# Convert raster to matrix then to data frame
anuran_sr_df <- raster::as.data.frame(raster::rasterToPoints(anuran_sr)) %>%
    dplyr::rename(species_n = layer)
aquatic_sr_df <- raster::as.data.frame(raster::rasterToPoints(aquatic_sr)) %>%
    dplyr::rename(aquatic_n = layer)
arboreal_sr_df <- raster::as.data.frame(raster::rasterToPoints(arboreal_sr)) %>%
    dplyr::rename(arboreal_n = layer)
fossorial_sr_df <- raster::as.data.frame(raster::rasterToPoints(fossorial_sr)) %>%
    dplyr::rename(fossorial_n = layer)
ground_sr_df <- raster::as.data.frame(raster::rasterToPoints(ground_sr)) %>%
    dplyr::rename(ground_n = layer)
semi_aq_sr_df <- raster::as.data.frame(raster::rasterToPoints(semi_aq_sr)) %>%
    dplyr::rename(semi_aq_n = layer)
stream_sr_df <- raster::as.data.frame(raster::rasterToPoints(stream_sr)) %>%
    dplyr::rename(stream_n = layer)

There are 5636 anuran species from the IUCN Red List used for the analysis.

Calculate AI and PDSI

High resolution (~4 km2) global dataset on precipitation (mm/month) and potential evapotranspiration (mm/month) were obtained from Abatzoglou et al. (2018) under 1) the current climate (1970–2000), 2) an intermediate greenhouse gas emission scenario of +2°C (Shared Socioeconomic Pathway 2–4.5; SPP2–4.5), and 3) a high greenhouse gas emission or “business-as-usual” scenario of +4°C (SSP5–8.5) by 2080–2099 (Fig. S1a–f).

We obtained a self-calibrated PDSI with Penman–Monteith potential evapotranspiration representing the current climate (1970–2000) and an intermediate and high emission scenario by 2080–2099 (SSP2–4.5 and SSP5-8.5) from Zhao and Dai (2022). The SSP2–4.5 and SSP5–8.5 scenarios were based on the average of 25 CMIP6 models of precipitation, evapotranspiration, soil moisture, and runoff (Eyring et al., 2016), where the mean annual surface temperature is expected to increase by 2.7°C (2.1–3.5°C range) and 4.4°C (3.3–5.7°C range), respectively by 2080–2100 (IPCC, 2021).

# Import the downloaded files
ppt_rast <- raster::projectRaster(raster::stack(x = file.path(spatial_path, "TerraClimate19812010_ppt.nc")),
    anuran_sr)  # Precipitation year 1981-2010 - Pr (mm)
pet_rast <- raster::projectRaster(raster::stack(x = file.path(spatial_path, "TerraClimate19812010_pet.nc")),
    anuran_sr)  # Evapotranspiration 1981-2010 - ET0 (mm)

# +2C and +4C future scenarios
ppt_2C_rast <- raster::projectRaster(raster::stack(x = file.path(spatial_path, "TerraClimate2C_ppt.nc")),
    anuran_sr)
pet_2C_rast <- raster::projectRaster(raster::stack(x = file.path(spatial_path, "TerraClimate2C_pet.nc")),
    anuran_sr)
ppt_4C_rast <- raster::projectRaster(raster::stack(x = file.path(spatial_path, "TerraClimate4C_ppt.nc")),
    anuran_sr)
pet_4C_rast <- raster::projectRaster(raster::stack(x = file.path(spatial_path, "TerraClimate4C_pet.nc")),
    anuran_sr)

# Obtain mean values from 1981-2010
ppt_mean_rast <- raster::calc(ppt_rast, fun = mean, na.rm = TRUE)
pet_mean_rast <- raster::calc(pet_rast, fun = mean, na.rm = TRUE)
ppt_2C_mean_rast <- raster::calc(ppt_2C_rast, fun = mean, na.rm = TRUE)
pet_2C_mean_rast <- raster::calc(pet_2C_rast, fun = mean, na.rm = TRUE)
ppt_4C_mean_rast <- raster::calc(ppt_4C_rast, fun = mean, na.rm = TRUE)
pet_4C_mean_rast <- raster::calc(pet_4C_rast, fun = mean, na.rm = TRUE)

# Obtain mean values from 10-year monthly PDSI
PDSI_ssp245_rast <- raster::stack(x = file.path(spatial_path, "pdsisc.monthly.1900-2100.r2.5x2.5.EnsAvg25Models.TP2.ipe-2.ssp245.nc"))
PDSI_ssp585_rast <- raster::stack(x = file.path(spatial_path, "pdsisc.monthly.1900-2100.r2.5x2.5.EnsAvg25Models.TP2.ipe-2.ssp585.nc"))

PDSI_cur_rast <- raster::subset(PDSI_ssp245_rast, grep("X197.*|X198.*|X199.*", names(PDSI_ssp245_rast),
    value = T))
PDSI_2C_rast <- raster::subset(PDSI_ssp245_rast, grep("X207.*|X208.*|X209.*", names(PDSI_ssp245_rast),
    value = T))
PDSI_4C_rast <- raster::subset(PDSI_ssp585_rast, grep("X207.*|X208.*|X209.*", names(PDSI_ssp585_rast),
    value = T))

PDSI_cur_mean_rast <- raster::calc(PDSI_cur_rast, fun = mean, na.rm = TRUE)
PDSI_2C_mean_rast <- raster::calc(PDSI_2C_rast, fun = mean, na.rm = TRUE)
PDSI_4C_mean_rast <- raster::calc(PDSI_4C_rast, fun = mean, na.rm = TRUE)

# Calculate aridity index [Precipitation (ppt) / Evapotranspiration (pet)]
ai_rast <- raster::overlay(x = ppt_mean_rast, y = pet_mean_rast, fun = function(x,
    y) {
    return(x/y)
})
ai_2C_rast <- raster::overlay(x = ppt_2C_mean_rast, y = pet_2C_mean_rast, fun = function(x,
    y) {
    return(x/y)
})
ai_4C_rast <- raster::overlay(x = ppt_4C_mean_rast, y = pet_4C_mean_rast, fun = function(x,
    y) {
    return(x/y)
})

# Calculate change in PDSI Reproject intensity raster to match anuran_sr
PDSI_cur_mean_rast <- raster::projectRaster(PDSI_cur_mean_rast, anuran_sr)
PDSI_2C_mean_rast <- raster::projectRaster(PDSI_2C_mean_rast, anuran_sr)
PDSI_4C_mean_rast <- raster::projectRaster(PDSI_4C_mean_rast, anuran_sr)

PDSI_2C_diff_rast <- raster::overlay(x = PDSI_cur_mean_rast, y = PDSI_2C_mean_rast,
    fun = function(x, y) {
        return(y - x)
    })
PDSI_4C_diff_rast <- raster::overlay(x = PDSI_cur_mean_rast, y = PDSI_4C_mean_rast,
    fun = function(x, y) {
        return(y - x)
    })

# Convert raster to matrix then to data frame
ai_df <- raster::as.data.frame(raster::rasterToPoints(ai_rast))
ai_2C_df <- raster::as.data.frame(raster::rasterToPoints(ai_2C_rast))
ai_4C_df <- raster::as.data.frame(raster::rasterToPoints(ai_4C_rast))

PDSI_2C_diff_df <- raster::as.data.frame(raster::rasterToPoints(PDSI_2C_diff_rast))
PDSI_4C_diff_df <- raster::as.data.frame(raster::rasterToPoints(PDSI_4C_diff_rast))

# Convert aridity index into category
ai_df <- ai_df %>%
    # Recode
dplyr::mutate(category = case_when(is.infinite(layer) ~ "Humid", layer >= 0.65 ~
    "Humid", layer >= 0.5 & layer < 0.65 ~ "Dry sub-humid", layer >= 0.2 & layer <
    0.5 ~ "Semi-arid", layer >= 0.05 & layer < 0.2 ~ "Arid", layer < 0.05 ~ "Hyper-arid")) %>%
    # Convert to ordered factor
dplyr::mutate(category = factor(category, levels = c("Hyper-arid", "Arid", "Semi-arid",
    "Dry sub-humid", "Humid"), ordered = TRUE))

ai_2C_df <- ai_2C_df %>%
    # Recode
dplyr::mutate(category = case_when(is.infinite(layer) ~ "Humid", layer >= 0.65 ~
    "Humid", layer >= 0.5 & layer < 0.65 ~ "Dry sub-humid", layer >= 0.2 & layer <
    0.5 ~ "Semi-arid", layer >= 0.05 & layer < 0.2 ~ "Arid", layer < 0.05 ~ "Hyper-arid")) %>%
    # Convert to ordered factor
dplyr::mutate(category = factor(category, levels = c("Hyper-arid", "Arid", "Semi-arid",
    "Dry sub-humid", "Humid"), ordered = TRUE))

ai_4C_df <- ai_4C_df %>%
    # Recode
dplyr::mutate(category = case_when(is.infinite(layer) ~ "Humid", layer >= 0.65 ~
    "Humid", layer >= 0.5 & layer < 0.65 ~ "Dry sub-humid", layer >= 0.2 & layer <
    0.5 ~ "Semi-arid", layer >= 0.05 & layer < 0.2 ~ "Arid", layer < 0.05 ~ "Hyper-arid")) %>%
    # Convert to ordered factor
dplyr::mutate(category = factor(category, levels = c("Hyper-arid", "Arid", "Semi-arid",
    "Dry sub-humid", "Humid"), ordered = TRUE))

# Convert PDSI to category
PDSI_2C_diff_df <- PDSI_2C_diff_df %>%
    # Recode
dplyr::mutate(change_2C = case_when(layer >= 4 ~ "4", layer >= 3 & layer < 4 ~ "3",
    layer >= 2 & layer < 3 ~ "2", layer >= 1 & layer < 2 ~ "1", layer >= -1 & layer <
        1 ~ "0", layer >= -2 & layer < -1 ~ "-1", layer >= -3 & layer < -2 ~ "-2",
    layer >= -4 & layer < -3 ~ "-3", layer < -4 ~ "-4")) %>%
    # Convert to ordered factor
dplyr::mutate(change_2C = factor(change_2C, levels = c("-4", "-3", "-2", "-1", "0",
    "1", "2", "3", "4"), ordered = TRUE))

PDSI_4C_diff_df <- PDSI_4C_diff_df %>%
    # Recode
dplyr::mutate(change_4C = case_when(layer >= 4 ~ "4", layer >= 3 & layer < 4 ~ "3",
    layer >= 2 & layer < 3 ~ "2", layer >= 1 & layer < 2 ~ "1", layer >= -1 & layer <
        1 ~ "0", layer >= -2 & layer < -1 ~ "-1", layer >= -3 & layer < -2 ~ "-2",
    layer >= -4 & layer < -3 ~ "-3", layer < -4 ~ "-4")) %>%
    # Convert to ordered factor
dplyr::mutate(change_4C = factor(change_4C, levels = c("-4", "-3", "-2", "-1", "0",
    "1", "2", "3", "4"), ordered = TRUE))
# Crop and mask
world <- rgdal::readOGR(file.path(spatial_path, "ne_50m_land/ne_50m_land.shp"))
## OGR data source with driver: ESRI Shapefile 
## Source: "/Users/nicholaswu/Library/CloudStorage/OneDrive-WesternSydneyUniversity/Drought project/Spatial data/ne_50m_land/ne_50m_land.shp", layer: "ne_50m_land"
## with 1420 features
## It has 3 fields
## Integer64 fields read as strings:  scalerank
world_spdf <- sp::SpatialPolygonsDataFrame(world, world@data)

# Precipitation
ppt_curr_plot <- raster::as.data.frame(raster::rasterToPoints(ppt_mean_rast)) %>%
    ggplot() + geom_raster(aes(y = y, x = x, fill = layer)) + geom_polygon(data = world_spdf,
    aes(x = long, y = lat, group = group), colour = "#64686b", fill = NA, size = 0.1) +
    scale_fill_continuous_sequential(palette = "YlGnBu", lim = c(0, 650), name = "Precipitation (mm)") +
    ggtitle("Current (1981-2010)") + scale_y_continuous(limits = c(-60, 90), expand = c(0,
    0)) + scale_x_continuous(limits = c(-180, 180), expand = c(0, 0)) + guides(fill = guide_colourbar(barwidth = 10,
    barheight = 0.3, label.position = "bottom")) + theme_void() + ylab(NULL) + xlab(NULL) +
    theme(axis.title = element_blank(), axis.text = element_blank(), axis.ticks = element_blank(),
        plot.title = element_text(size = 10), legend.title = element_text(size = 8),
        legend.position = "bottom") + coord_fixed(ratio = 1)

ppt_2C_plot <- raster::as.data.frame(raster::rasterToPoints(ppt_2C_mean_rast)) %>%
    ggplot() + geom_raster(aes(y = y, x = x, fill = layer)) + geom_polygon(data = world_spdf,
    aes(x = long, y = lat, group = group), colour = "#64686b", fill = NA, size = 0.1) +
    scale_fill_continuous_sequential(palette = "YlGnBu", lim = c(0, 650)) + ggtitle("+2°C (2080-2100)") +
    scale_y_continuous(limits = c(-60, 90), expand = c(0, 0)) + scale_x_continuous(limits = c(-180,
    180), expand = c(0, 0)) + theme_void() + ylab(NULL) + xlab(NULL) + theme(axis.title = element_blank(),
    axis.text = element_blank(), axis.ticks = element_blank(), plot.title = element_text(size = 10)) +
    coord_fixed(ratio = 1)

ppt_4C_plot <- raster::as.data.frame(raster::rasterToPoints(ppt_4C_mean_rast)) %>%
    ggplot() + geom_raster(aes(y = y, x = x, fill = layer)) + geom_polygon(data = world_spdf,
    aes(x = long, y = lat, group = group), colour = "#64686b", fill = NA, size = 0.1) +
    scale_fill_continuous_sequential(palette = "YlGnBu", lim = c(0, 650)) + ggtitle("+4°C (2080-2100)") +
    scale_y_continuous(limits = c(-60, 90), expand = c(0, 0)) + scale_x_continuous(limits = c(-180,
    180), expand = c(0, 0)) + theme_void() + ylab(NULL) + xlab(NULL) + theme(axis.title = element_blank(),
    axis.text = element_blank(), axis.ticks = element_blank(), plot.title = element_text(size = 10)) +
    coord_fixed(ratio = 1)

ppt_legend <- cowplot::get_legend(ppt_curr_plot)

ppt_prow <- cowplot::plot_grid(ppt_curr_plot + theme(legend.position = "none"), ppt_2C_plot +
    theme(legend.position = "none"), ppt_4C_plot + theme(legend.position = "none"),
    align = "v", ncol = 3, labels = c("a", "b", "c"))

ppt_plots <- cowplot::plot_grid(ppt_prow, ppt_legend, ncol = 1, rel_heights = c(1,
    0.1))

# Evapotranspiration
pet_curr_plot <- raster::as.data.frame(raster::rasterToPoints(pet_mean_rast)) %>%
    ggplot() + geom_raster(aes(y = y, x = x, fill = layer)) + geom_polygon(data = world_spdf,
    aes(x = long, y = lat, group = group), colour = "#64686b", fill = NA, size = 0.1) +
    scale_fill_continuous_sequential(palette = "Rocket", lim = c(0, 300), name = "Evapotranspiration (mm)") +
    scale_y_continuous(limits = c(-60, 90), expand = c(0, 0)) + scale_x_continuous(limits = c(-180,
    180), expand = c(0, 0)) + guides(fill = guide_colourbar(barwidth = 10, barheight = 0.3,
    label.position = "bottom")) + theme_void() + ylab(NULL) + xlab(NULL) + theme(axis.title = element_blank(),
    axis.text = element_blank(), axis.ticks = element_blank(), plot.title = element_text(size = 10),
    legend.title = element_text(size = 8), legend.position = "bottom") + coord_fixed(ratio = 1)

pet_2C_plot <- raster::as.data.frame(raster::rasterToPoints(pet_2C_mean_rast)) %>%
    ggplot() + geom_raster(aes(y = y, x = x, fill = layer)) + geom_polygon(data = world_spdf,
    aes(x = long, y = lat, group = group), colour = "#64686b", fill = NA, size = 0.1) +
    scale_fill_continuous_sequential(palette = "Rocket", lim = c(0, 300)) + scale_y_continuous(limits = c(-60,
    90), expand = c(0, 0)) + scale_x_continuous(limits = c(-180, 180), expand = c(0,
    0)) + theme_void() + ylab(NULL) + xlab(NULL) + theme(axis.title = element_blank(),
    axis.text = element_blank(), axis.ticks = element_blank(), plot.title = element_text(size = 10)) +
    coord_fixed(ratio = 1)

pet_4C_plot <- raster::as.data.frame(raster::rasterToPoints(pet_4C_mean_rast)) %>%
    ggplot() + geom_raster(aes(y = y, x = x, fill = layer)) + geom_polygon(data = world_spdf,
    aes(x = long, y = lat, group = group), colour = "#64686b", fill = NA, size = 0.1) +
    scale_fill_continuous_sequential(palette = "Rocket", lim = c(0, 300)) + scale_y_continuous(limits = c(-60,
    90), expand = c(0, 0)) + scale_x_continuous(limits = c(-180, 180), expand = c(0,
    0)) + theme_void() + ylab(NULL) + xlab(NULL) + theme(axis.title = element_blank(),
    axis.text = element_blank(), axis.ticks = element_blank(), plot.title = element_text(size = 10)) +
    coord_fixed(ratio = 1)

pet_legend <- cowplot::get_legend(pet_curr_plot)

pet_prow <- cowplot::plot_grid(pet_curr_plot + theme(legend.position = "none"), pet_2C_plot +
    theme(legend.position = "none"), pet_4C_plot + theme(legend.position = "none"),
    align = "v", ncol = 3, labels = c("d", "e", "f"))

pet_plots <- cowplot::plot_grid(pet_prow, pet_legend, ncol = 1, rel_heights = c(1,
    0.1))

# Aridity Index
arid_col <- c("#8E063B", "#CB6D53", "#E99A2C", "#F5D579", "white")
ai_curr_plot <- ggplot() + geom_raster(data = ai_df, aes(y = y, x = x, fill = category)) +
    geom_polygon(data = world_spdf, aes(x = long, y = lat, group = group), colour = "#64686b",
        fill = NA, size = 0.1) + scale_fill_manual(values = arid_col, guide = guide_legend(reverse = TRUE),
    name = "Aridity Index") + ylab(NULL) + xlab(NULL) + scale_y_continuous(limits = c(-60,
    90), expand = c(0, 0)) + scale_x_continuous(limits = c(-180, 180), expand = c(0,
    0)) + theme_void() + theme(axis.title = element_blank(), axis.text = element_blank(),
    axis.ticks = element_blank(), plot.title = element_text(size = 10), legend.title = element_text(size = 8),
    legend.key.size = unit(0.2, "cm"), legend.position = "bottom") + coord_fixed(ratio = 1)

ai_2C_plot <- ggplot() + geom_raster(data = ai_2C_df, aes(y = y, x = x, fill = category)) +
    geom_polygon(data = world_spdf, aes(x = long, y = lat, group = group), colour = "#64686b",
        fill = NA, size = 0.1) + scale_fill_manual(values = arid_col, guide = guide_legend(reverse = TRUE),
    name = "Aridity Index") + ylab(NULL) + xlab(NULL) + scale_y_continuous(limits = c(-60,
    90), expand = c(0, 0)) + scale_x_continuous(limits = c(-180, 180), expand = c(0,
    0)) + theme_void() + theme(axis.title = element_blank(), axis.text = element_blank(),
    axis.ticks = element_blank(), plot.title = element_text(size = 10)) + coord_fixed(ratio = 1)

ai_4C_plot <- ggplot() + geom_raster(data = ai_4C_df, aes(y = y, x = x, fill = category)) +
    geom_polygon(data = world_spdf, aes(x = long, y = lat, group = group), colour = "#64686b",
        fill = NA, size = 0.1) + scale_fill_manual(values = arid_col, guide = guide_legend(reverse = TRUE),
    name = "Aridity Index") + ylab(NULL) + xlab(NULL) + scale_y_continuous(limits = c(-60,
    90), expand = c(0, 0)) + scale_x_continuous(limits = c(-180, 180), expand = c(0,
    0)) + theme_void() + theme(axis.title = element_blank(), axis.text = element_blank(),
    axis.ticks = element_blank(), plot.title = element_text(size = 10)) + coord_fixed(ratio = 1)

ai_legend <- cowplot::get_legend(ai_curr_plot)

ai_prow <- cowplot::plot_grid(ai_curr_plot + theme(legend.position = "none"), ai_2C_plot +
    theme(legend.position = "none"), ai_4C_plot + theme(legend.position = "none"),
    align = "v", ncol = 3, labels = c("g", "h", "i"))

ai_plots <- cowplot::plot_grid(ai_prow, ai_legend, ncol = 1, rel_heights = c(1, 0.1))

cowplot::plot_grid(ppt_plots, pet_plots, ai_plots, ncol = 1)

Fig. S1. Climate data used to calculate the aridity index. Mean precipitation (mm) for (a) the current scenario from 1981-2010, (b) under an intermediate emission scenario (Shared Socioeconomic Pathways 2 - 4.5; SSP2-4.5), and (c) under a high emission scenario (SSP5-8.5) by 2080-2100. Mean potential evapotranspiration (mm) for (d) the current scenario from 1981-2010, (e) under an intermediate emission scenario (SSP2-4.5), and (f) under a high emission scenario (SSP5-8.5) by 2080-2100. Calculated Aridity Index for (g) the current scenario from 1981-2010, (h) under an intermediate emission scenario (SSP2-4.5), and (i) under a high emession scenario (SSP5-8.5) by 2080-2100.

AI risk

To examine the relationship of species richness with aridity, the number of species per gird cell was overlapped with the aridity raster layer, where each grid was assigned an AI category. The change in species richness between the current and projected (either +2 or +4 °C warming) AI category was calculated as the change in AI category grids (resolution 0.5° for decimal degree coordinates) occupied by anurans relative to the future projection. A decrease indicates reduced number of species with the assigned AI category and vice versa.

# Merge aridity index, +4C and amphibian species richness
ai_sp_df <- ai_df %>%
    dplyr::full_join(ai_2C_df, by = c("x", "y")) %>%
    dplyr::full_join(ai_4C_df, by = c("x", "y")) %>%
    dplyr::full_join(anuran_sr_df, by = c("x", "y")) %>%
    dplyr::full_join(aquatic_sr_df, by = c("x", "y")) %>%
    dplyr::full_join(arboreal_sr_df, by = c("x", "y")) %>%
    dplyr::full_join(fossorial_sr_df, by = c("x", "y")) %>%
    dplyr::full_join(ground_sr_df, by = c("x", "y")) %>%
    dplyr::full_join(semi_aq_sr_df, by = c("x", "y")) %>%
    dplyr::full_join(stream_sr_df, by = c("x", "y")) %>%
    dplyr::rename(aridity = layer.x, aridity_2C = layer.y, aridity_4C = layer, category = category.x,
        category_2C = category.y, category_4C = category) %>%
    drop_na(category)

# Calculate grid cells occupied for current climate
ai_sp_sum <- data.frame(ai_sp_df %>%
    dplyr::group_by(category) %>%
    dplyr::summarise(species_n = length(species_n[!is.na(species_n)]), aquatic_n = length(aquatic_n[!is.na(aquatic_n)]),
        arboreal_n = length(arboreal_n[!is.na(arboreal_n)]), fossorial_n = length(fossorial_n[!is.na(fossorial_n)]),
        ground_n = length(ground_n[!is.na(ground_n)]), semi_aq_n = length(semi_aq_n[!is.na(semi_aq_n)]),
        stream_n = length(stream_n[!is.na(stream_n)]))) %>%
    dplyr::mutate(scenario = "Current", all_freq = species_n/sum(species_n) * 100,
        aquatic_freq = aquatic_n/sum(aquatic_n) * 100, arboreal_freq = arboreal_n/sum(arboreal_n) *
            100, fossorial_freq = fossorial_n/sum(fossorial_n) * 100, ground_freq = ground_n/sum(ground_n) *
            100, semi_aq_freq = semi_aq_n/sum(semi_aq_n) * 100, stream_freq = stream_n/sum(stream_n) *
            100)

# Calculate grid cells occupied for future climate
ai_2C_sp_sum <- data.frame(ai_sp_df %>%
    dplyr::group_by(category_2C) %>%
    dplyr::summarise(species_n = length(species_n[!is.na(species_n)]), aquatic_n = length(aquatic_n[!is.na(aquatic_n)]),
        arboreal_n = length(arboreal_n[!is.na(arboreal_n)]), fossorial_n = length(fossorial_n[!is.na(fossorial_n)]),
        ground_n = length(ground_n[!is.na(ground_n)]), semi_aq_n = length(semi_aq_n[!is.na(semi_aq_n)]),
        stream_n = length(stream_n[!is.na(stream_n)]))) %>%
    dplyr::mutate(scenario = "SSP245", all_freq = species_n/sum(species_n) * 100,
        aquatic_freq = aquatic_n/sum(aquatic_n) * 100, arboreal_freq = arboreal_n/sum(arboreal_n) *
            100, fossorial_freq = fossorial_n/sum(fossorial_n) * 100, ground_freq = ground_n/sum(ground_n) *
            100, semi_aq_freq = semi_aq_n/sum(semi_aq_n) * 100, stream_freq = stream_n/sum(stream_n) *
            100) %>%
    dplyr::rename(category = category_2C)

ai_4C_sp_sum <- data.frame(ai_sp_df %>%
    dplyr::group_by(category_4C) %>%
    dplyr::summarise(species_n = length(species_n[!is.na(species_n)]), aquatic_n = length(aquatic_n[!is.na(aquatic_n)]),
        arboreal_n = length(arboreal_n[!is.na(arboreal_n)]), fossorial_n = length(fossorial_n[!is.na(fossorial_n)]),
        ground_n = length(ground_n[!is.na(ground_n)]), semi_aq_n = length(semi_aq_n[!is.na(semi_aq_n)]),
        stream_n = length(stream_n[!is.na(stream_n)]))) %>%
    dplyr::mutate(scenario = "SSP585", all_freq = species_n/sum(species_n) * 100,
        aquatic_freq = aquatic_n/sum(aquatic_n) * 100, rboreal_freq = arboreal_n/sum(arboreal_n) *
            100, fossorial_freq = fossorial_n/sum(fossorial_n) * 100, ground_freq = ground_n/sum(ground_n) *
            100, semi_aq_freq = semi_aq_n/sum(semi_aq_n) * 100, stream_freq = stream_n/sum(stream_n) *
            100) %>%
    dplyr::rename(category = category_4C)

PDSI risk

With a monthly prediction of PDSI from 1950 to 2100 globally available from Zhao and Dai (2022), we classified future drought risk in three ways: 1) increase in drought intensity (magnitude change in PDSI), increase in drought frequency (monthly PDSI counts below -2 per year), increase in duration (number of consecutive months with PDSI values below -2). Change in drought intensity (ΔPDSI[intensity]), frequency (ΔPDSI[frequency]), and duration (ΔPDSI[duration]) under a +2 or +4 °C warming scenario (2080–2100) was calculated relative to the 1970–2000 monthly climatology per gird cell (ΔPDSI = PDSI[future] – PDSI[current]). Note, the temporal resolution was limited to monthly variation as the PDSI was developed to monitor long-term meteorological drought.

# Change in PDSI intensity
PDSI_sp_df <- anuran_sr_df %>%
    dplyr::full_join(PDSI_2C_diff_df, by = c("x", "y")) %>%
    dplyr::full_join(PDSI_4C_diff_df, by = c("x", "y")) %>%
    dplyr::full_join(aquatic_sr_df, by = c("x", "y")) %>%
    dplyr::full_join(arboreal_sr_df, by = c("x", "y")) %>%
    dplyr::full_join(fossorial_sr_df, by = c("x", "y")) %>%
    dplyr::full_join(ground_sr_df, by = c("x", "y")) %>%
    dplyr::full_join(semi_aq_sr_df, by = c("x", "y")) %>%
    dplyr::full_join(stream_sr_df, by = c("x", "y")) %>%
    dplyr::rename(PDSI_2C = layer.x, PDSI_4C = layer.y) %>%
    drop_na(change_2C) %>%
    filter(species_n != "NA")

# Calculate grid cells occupied for current climate
PDSI_sp_2C <- data.frame(PDSI_sp_df %>%
    dplyr::group_by(change_2C) %>%
    dplyr::summarise(species_n = length(species_n[!is.na(species_n)]), aquatic_n = length(aquatic_n[!is.na(aquatic_n)]),
        arboreal_n = length(arboreal_n[!is.na(arboreal_n)]), fossorial_n = length(fossorial_n[!is.na(fossorial_n)]),
        ground_n = length(ground_n[!is.na(ground_n)]), semi_aq_n = length(semi_aq_n[!is.na(semi_aq_n)]),
        stream_n = length(stream_n[!is.na(stream_n)]))) %>%
    dplyr::mutate(all_freq = species_n/sum(species_n) * 100, aquatic_freq = aquatic_n/sum(aquatic_n) *
        100, arboreal_freq = arboreal_n/sum(arboreal_n) * 100, fossorial_freq = fossorial_n/sum(fossorial_n) *
        100, ground_freq = ground_n/sum(ground_n) * 100, semi_aq_freq = semi_aq_n/sum(semi_aq_n) *
        100, stream_freq = stream_n/sum(stream_n) * 100)

PDSI_sp_4C <- data.frame(PDSI_sp_df %>%
    dplyr::group_by(change_4C) %>%
    dplyr::summarise(species_n = length(species_n[!is.na(species_n)]), aquatic_n = length(aquatic_n[!is.na(aquatic_n)]),
        arboreal_n = length(arboreal_n[!is.na(arboreal_n)]), fossorial_n = length(fossorial_n[!is.na(fossorial_n)]),
        ground_n = length(ground_n[!is.na(ground_n)]), semi_aq_n = length(semi_aq_n[!is.na(semi_aq_n)]),
        stream_n = length(stream_n[!is.na(stream_n)]))) %>%
    dplyr::mutate(all_freq = species_n/sum(species_n) * 100, aquatic_freq = aquatic_n/sum(aquatic_n) *
        100, arboreal_freq = arboreal_n/sum(arboreal_n) * 100, fossorial_freq = fossorial_n/sum(fossorial_n) *
        100, ground_freq = ground_n/sum(ground_n) * 100, semi_aq_freq = semi_aq_n/sum(semi_aq_n) *
        100, stream_freq = stream_n/sum(stream_n) * 100)
# Calculate frequency of moderate to extreme drought (<-2 PDSI) per year.

# Temporal change in PDSI intensity
PDSI_2C_time_df <- raster::as.data.frame(raster::rasterToPoints(PDSI_ssp245_rast))
PDSI_4C_time_df <- raster::as.data.frame(raster::rasterToPoints(PDSI_ssp585_rast))

# Convert wide to long
freq_2C_df <- PDSI_2C_time_df %>%
    tidyr::pivot_longer(!c("x", "y"), names_to = "dates", values_to = "PDSI") %>%
    data.frame() %>%
    tidyr::separate(dates, c("year", "months")) %>%
    dplyr::mutate(year = as.numeric(substring(year, 2))) %>%
    dplyr::filter(year >= 1950 & year != 2100)

freq_4C_df <- PDSI_4C_time_df %>%
    tidyr::pivot_longer(!c("x", "y"), names_to = "dates", values_to = "PDSI") %>%
    data.frame() %>%
    tidyr::separate(dates, c("year", "months")) %>%
    dplyr::mutate(year = as.numeric(substring(year, 2))) %>%
    dplyr::filter(year >= 1950 & year != 2100)

# Summarise average monthly counts <-2 PDSI from 1970 to 1999 or 2080 to 2100
freq_mean_df <- freq_2C_df %>%
    dplyr::filter(year >= 1970 & year <= 1999) %>%
    dplyr::group_by(x, y, year) %>%
    dplyr::summarise(count = sum(PDSI < -2)) %>%
    dplyr::group_by(x, y) %>%
    dplyr::summarise(mean_curr = mean(count))

freq_2C_diff_df <- freq_2C_df %>%
    dplyr::filter(year >= 2080 & year != 2100) %>%
    dplyr::group_by(x, y, year) %>%
    dplyr::summarise(count = sum(PDSI < -2)) %>%
    dplyr::group_by(x, y) %>%
    dplyr::summarise(mean_2C = mean(count)) %>%
    dplyr::inner_join(freq_mean_df, by = c(x = "x", y = "y")) %>%
    dplyr::mutate(diff_2C = mean_2C - mean_curr)

freq_4C_diff_df <- freq_4C_df %>%
    dplyr::filter(year >= 2080 & year != 2100) %>%
    dplyr::group_by(x, y, year) %>%
    dplyr::summarise(count = sum(PDSI < -2)) %>%
    dplyr::group_by(x, y) %>%
    dplyr::summarise(mean_4C = mean(count)) %>%
    dplyr::inner_join(freq_2C_diff_df, by = c(x = "x", y = "y")) %>%
    dplyr::mutate(diff_4C = mean_4C - mean_curr)
# Calculate duration of moderate to extreme drought (<-2 PDSI) from 1970 to
# 1999
dur_curr_df <- freq_2C_df %>%
    dplyr::mutate(bin = ifelse(PDSI < -2, 1, 0)) %>%
    dplyr::filter(year >= 1970 & year <= 1999) %>%
    dplyr::group_by(x, y) %>%
    dplyr::summarise(mean_curr = mean(rle(bin)$lengths[rle(bin)$values == 1])) %>%
    replace(is.na(.), 0)

# Calculate duration of moderate to extreme drought (<-2 PDSI) from 2080 to
# 2100
dur_2C_df <- freq_2C_df %>%
    dplyr::mutate(bin = ifelse(PDSI < -2, 1, 0)) %>%
    dplyr::filter(year >= 2080 & year != 2100) %>%
    dplyr::group_by(x, y) %>%
    dplyr::summarise(mean_2C = mean(rle(bin)$lengths[rle(bin)$values == 1])) %>%
    replace(is.na(.), 0) %>%
    dplyr::inner_join(dur_curr_df, by = c(x = "x", y = "y")) %>%
    dplyr::mutate(diff_2C = mean_2C - mean_curr)

dur_4C_df <- freq_4C_df %>%
    dplyr::mutate(bin = ifelse(PDSI < -2, 1, 0)) %>%
    dplyr::group_by(x, y) %>%
    dplyr::filter(year >= 2080 & year != 2100) %>%
    dplyr::summarise(mean_4C = mean(rle(bin)$lengths[rle(bin)$values == 1])) %>%
    replace(is.na(.), 0) %>%
    dplyr::inner_join(dur_2C_df, by = c(x = "x", y = "y")) %>%
    dplyr::mutate(diff_4C = mean_4C - mean_curr)

The simultaneous risk of drought intensity, frequency, and duration within a grid cell that are occupied by anurans was calculated by converting each risk category as binary. Gird cells with a ΔPDSI[intensity] below -1 (indicating a decrease in PDSI) were assigned a ‘1’ binary. Both ΔPDSI[frequency] and ΔPDSI[duration] were assigned a binary of ‘1’ if the grid cell has a value of 1 month or higher (indicating increase in frequency or duration relative to current scenario). The number of overlapping binaries were summed up per grid cell. Therefore, a risk factor of 2 indicate anurans in the assigned grid cell are at increasing risk of two drought events. We estimated which species assemblages were risk to drought using an arbitrary risk factor (species richness × drought risk), where grid cells with high drought risk and high species richness have higher species-assemblage risk than gird cells with high drought risk and low species richness (low species-assemblage risk).

# Intensity
names(PDSI_2C_diff_rast) <- "delta_int_2C"
names(PDSI_4C_diff_rast) <- "delta_int_4C"

# Frequency
freq_diff_rast <- rasterFromXYZ(freq_4C_diff_df) # convert to raster
crs(freq_diff_rast) <- "+proj=longlat +datum=WGS84 +no_defs +ellps=WGS84 +towgs84=0,0,0"
freq_diff_rast <- projectRaster(freq_diff_rast, anuran_sr) # match anuran extent
freq_diff_df   <- raster::as.data.frame(raster::rasterToPoints(freq_diff_rast))

PDSI_freq_diff <- subset(freq_diff_rast, 4:5)
names(PDSI_freq_diff) <- c("delta_freq_2C", "delta_freq_4C")

# Duration
dur_diff_rast <- raster::rasterFromXYZ(dur_4C_df) # convert to raster
crs(dur_diff_rast) <- "+proj=longlat +datum=WGS84 +no_defs +ellps=WGS84 +towgs84=0,0,0"
dur_diff_rast <- raster::projectRaster(dur_diff_rast, anuran_sr) # match anuran extent
dur_diff_df <- raster::as.data.frame(raster::rasterToPoints(dur_diff_rast))

PDSI_dur_diff  <- subset(dur_diff_rast, 4:5)
names(PDSI_dur_diff) <- c("delta_dur_2C", "delta_dur_4C")

# Combine relative PDSI metrics
PDSI_risk_comb_rast <- raster::stack(PDSI_2C_diff_rast, PDSI_4C_diff_rast, PDSI_freq_diff, PDSI_dur_diff, resample(anuran_sr, PDSI_4C_diff_rast))
                             
PDSI_risk_comb_df <- raster::as.data.frame(raster::rasterToPoints(PDSI_risk_comb_rast)) %>%
  dplyr::rename("sp_n" = layer) %>%
  dplyr::filter(!is.na(sp_n)) %>%
  dplyr::mutate(delta_int_2C_bin = ifelse(delta_int_2C < -1, 1, 0), # delta_PDSI < -1
         delta_int_4C_bin = ifelse(delta_int_4C < -1, 1, 0), # delta_PDSI < -1
         delta_freq_2C_bin = ifelse(delta_freq_2C >1, 1, 0), # month > 1
         delta_freq_4C_bin = ifelse(delta_freq_4C >1, 1, 0), # month > 1
         delta_dur_2C_bin = ifelse(delta_dur_2C >1, 1, 0), # month > 1
         delta_dur_4C_bin = ifelse(delta_dur_4C >1, 1, 0)) %>% # month > 1 
  dplyr::rowwise() %>%
  dplyr::mutate(count_2C = sum(delta_int_2C_bin, delta_freq_2C_bin, delta_dur_2C_bin, na.rm = T),
         
         count_4C = sum(delta_int_4C_bin, delta_freq_4C_bin, delta_dur_4C_bin, na.rm = T),
         risk_2C  = sp_n * count_2C,
         risk_4C  = sp_n * count_4C,
         count_2C = factor(count_2C, levels = c("3", "2", "1")),
         count_4C = factor(count_4C, levels = c("3", "2", "1"))
         )
# Combine absolute PDSI metrics
PDSI_ab_rast <- raster::stack(PDSI_cur_mean_rast, PDSI_2C_mean_rast, PDSI_4C_mean_rast,
    freq_diff_rast, dur_diff_rast, resample(anuran_sr, PDSI_4C_mean_rast))
PDSI_ab_rast_crop <- raster::mask(crop(PDSI_ab_rast, extent(world)), world)  # crop 

PDSI_ab_df <- raster::as.data.frame(raster::rasterToPoints(PDSI_ab_rast_crop)) %>%
    dplyr::rename(PDSI_cur = "layer.1", PDSI_2C = "layer.2", PDSI_4C = "layer.3",
        freq_cur = "mean_curr.1", freq_2C = "mean_2C.1", freq_4C = "mean_4C.1", dur_cur = "mean_curr.2",
        dur_2C = "mean_2C.2", dur_4C = "mean_4C.2", sp_n = "layer.4") %>%
    filter(sp_n != "NA")

colours_PDSI <- RColorBrewer::brewer.pal(9, "RdBu")

# Intensity
PDSI_cur_plot <- PDSI_ab_df %>%
    dplyr::mutate(PDSI_cur_cat = case_when(PDSI_cur >= 2 & PDSI_cur < 3 ~ "2", PDSI_cur >=
        1 & PDSI_cur < 2 ~ "1", PDSI_cur >= -1 & PDSI_cur < 1 ~ "0")) %>%
    dplyr::mutate(PDSI_cur_cat = factor(PDSI_cur_cat, levels = c("0", "1", "2"),
        ordered = TRUE)) %>%
    filter(PDSI_cur_cat != "NA") %>%
    ggplot() + geom_raster(aes(y = y, x = x, fill = PDSI_cur_cat)) + geom_polygon(data = world_spdf,
    aes(x = long, y = lat, group = group), colour = "#64686b", fill = NA, size = 0.1) +
    scale_fill_manual(values = c("#F7F7F7", "#D1E5F0", "#92C5DE")) + theme_void() +
    ylab(NULL) + xlab(NULL) + ggtitle("Mean PDSI intensity (1970–2000)") + scale_y_continuous(limits = c(-60,
    90), expand = c(0, 0)) + scale_x_continuous(limits = c(-180, 180), expand = c(0,
    0)) + theme(axis.title = element_blank(), axis.text = element_blank(), axis.ticks = element_blank(),
    plot.title = element_text(size = 10)) + coord_fixed(ratio = 1)  # fixed ratio

PDSI_2C_plot <- PDSI_ab_df %>%
    dplyr::mutate(PDSI_2C_cat = case_when(PDSI_2C >= 4 ~ "4", PDSI_2C >= 3 & PDSI_2C <
        4 ~ "3", PDSI_2C >= 2 & PDSI_2C < 3 ~ "2", PDSI_2C >= 1 & PDSI_2C < 2 ~ "1",
        PDSI_2C >= -1 & PDSI_2C < 1 ~ "0", PDSI_2C >= -2 & PDSI_2C < -1 ~ "-1", PDSI_2C >=
            -3 & PDSI_2C < -2 ~ "-2", PDSI_2C >= -4 & PDSI_2C < -3 ~ "-3", PDSI_2C <
            -4 ~ "-4")) %>%
    dplyr::mutate(PDSI_2C_cat = factor(PDSI_2C_cat, levels = c("-4", "-3", "-2",
        "-1", "0", "1", "2", "3", "4"), ordered = TRUE)) %>%
    filter(PDSI_2C_cat != "NA") %>%
    ggplot() + geom_raster(aes(y = y, x = x, fill = PDSI_2C_cat)) + geom_polygon(data = world_spdf,
    aes(x = long, y = lat, group = group), colour = "#64686b", fill = NA, size = 0.1) +
    scale_fill_manual(values = colours_PDSI) + theme_void() + ylab(NULL) + xlab(NULL) +
    ggtitle("Mean PDSI intensity (+2°C)") + scale_y_continuous(limits = c(-60, 90),
    expand = c(0, 0)) + scale_x_continuous(limits = c(-180, 180), expand = c(0, 0)) +
    theme(axis.title = element_blank(), axis.text = element_blank(), axis.ticks = element_blank(),
        plot.title = element_text(size = 10)) + coord_fixed(ratio = 1)  # fixed ratio

PDSI_4C_plot <- PDSI_ab_df %>%
    dplyr::mutate(PDSI_4C_cat = case_when(PDSI_4C >= 4 ~ "4", PDSI_4C >= 3 & PDSI_4C <
        4 ~ "3", PDSI_4C >= 2 & PDSI_4C < 3 ~ "2", PDSI_4C >= 1 & PDSI_4C < 2 ~ "1",
        PDSI_4C >= -1 & PDSI_4C < 1 ~ "0", PDSI_4C >= -2 & PDSI_4C < -1 ~ "-1", PDSI_4C >=
            -3 & PDSI_4C < -2 ~ "-2", PDSI_4C >= -4 & PDSI_4C < -3 ~ "-3", PDSI_4C <
            -4 ~ "-4")) %>%
    dplyr::mutate(PDSI_4C_cat = factor(PDSI_4C_cat, levels = c("-4", "-3", "-2",
        "-1", "0", "1", "2", "3", "4"), ordered = TRUE)) %>%
    filter(PDSI_4C_cat != "NA") %>%
    ggplot() + geom_raster(aes(y = y, x = x, fill = PDSI_4C_cat)) + geom_polygon(data = world_spdf,
    aes(x = long, y = lat, group = group), colour = "#64686b", fill = NA, size = 0.1) +
    scale_fill_manual(values = colours_PDSI, name = "PDSI", guide = guide_legend(reverse = TRUE,
        nrow = 1)) + theme_void() + ylab(NULL) + xlab(NULL) + ggtitle("Mean PDSI intensity (+4°C)") +
    scale_y_continuous(limits = c(-60, 90), expand = c(0, 0)) + scale_x_continuous(limits = c(-180,
    180), expand = c(0, 0)) + theme(axis.title = element_blank(), axis.text = element_blank(),
    axis.ticks = element_blank(), plot.title = element_text(size = 10), legend.title = element_text(size = 8),
    legend.key.height = unit(0.2, "cm"), legend.key.width = unit(0.2, "cm"), legend.position = "bottom") +
    coord_fixed(ratio = 1)  # fixed ratio

int_legend <- cowplot::get_legend(PDSI_4C_plot)

int_prow <- cowplot::plot_grid(PDSI_cur_plot + theme(legend.position = "none"), PDSI_2C_plot +
    theme(legend.position = "none"), PDSI_4C_plot + theme(legend.position = "none"),
    align = "v", ncol = 3, labels = c("a", "b", "c"))

int_plots <- cowplot::plot_grid(int_prow, int_legend, ncol = 1, rel_heights = c(1,
    0.1))

# Frequency
freq_cur_plot <- PDSI_ab_df %>%
    dplyr::mutate(freq_cur_cat = case_when(freq_cur > 0.1 & freq_cur < 1 ~ "<1")) %>%
    filter(freq_cur_cat != "NA") %>%
    ggplot() + geom_raster(aes(y = y, x = x, fill = freq_cur_cat)) + geom_polygon(data = world_spdf,
    aes(x = long, y = lat, group = group), colour = "#64686b", fill = NA, size = 0.1) +
    scale_fill_manual(values = "#ededed") + theme_void() + ylab(NULL) + xlab(NULL) +
    ggtitle("Mean drought frequency (1970–2000)") + scale_y_continuous(limits = c(-60,
    90), expand = c(0, 0)) + scale_x_continuous(limits = c(-180, 180), expand = c(0,
    0)) + theme(axis.title = element_blank(), axis.text = element_blank(), axis.ticks = element_blank(),
    plot.title = element_text(size = 10)) + coord_fixed(ratio = 1)  # fixed ratio

freq_2C_plot <- PDSI_ab_df %>%
    dplyr::mutate(freq_2C_cat = case_when(freq_2C >= 10 ~ "10-12", freq_2C >= 8 &
        freq_2C < 10 ~ "8-10", freq_2C >= 6 & freq_2C < 8 ~ "6-8", freq_2C >= 4 &
        freq_2C < 6 ~ "4-6", freq_2C >= 2 & freq_2C < 4 ~ "2-4", freq_2C >= 1 & freq_2C <
        2 ~ "1-2", freq_2C > 0.1 & freq_2C < 1 ~ "<1")) %>%
    dplyr::mutate(freq_2C_cat = factor(freq_2C_cat, levels = c("10-12", "8-10", "6-8",
        "4-6", "2-4", "1-2", "<1"), ordered = TRUE)) %>%
    filter(freq_2C_cat != "NA") %>%
    ggplot() + geom_raster(aes(y = y, x = x, fill = freq_2C_cat)) + geom_polygon(data = world_spdf,
    aes(x = long, y = lat, group = group), colour = "#64686b", fill = NA, size = 0.1) +
    scale_fill_manual(values = c("#67001F", "#B2182B", "#D6604D", "#F4A582", "#FDDBC7",
        "#FAE9DF", "#F7F7F7")) + theme_void() + ylab(NULL) + xlab(NULL) + ggtitle("Mean drought frequency (+2°C)") +
    scale_y_continuous(limits = c(-60, 90), expand = c(0, 0)) + scale_x_continuous(limits = c(-180,
    180), expand = c(0, 0)) + theme(axis.title = element_blank(), axis.text = element_blank(),
    axis.ticks = element_blank(), plot.title = element_text(size = 10)) + coord_fixed(ratio = 1)  # fixed ratio

freq_4C_plot <- PDSI_ab_df %>%
    dplyr::mutate(freq_4C_cat = case_when(freq_4C >= 10 ~ "10-12", freq_4C >= 8 &
        freq_4C < 10 ~ "8-10", freq_4C >= 6 & freq_4C < 8 ~ "6-8", freq_4C >= 4 &
        freq_4C < 6 ~ "4-6", freq_4C >= 2 & freq_4C < 4 ~ "2-4", freq_4C >= 1 & freq_4C <
        2 ~ "1-2", freq_4C > 0.1 & freq_4C < 1 ~ "<1")) %>%
    dplyr::mutate(freq_4C_cat = factor(freq_4C_cat, levels = c("10-12", "8-10", "6-8",
        "4-6", "2-4", "1-2", "<1"), ordered = TRUE)) %>%
    filter(freq_4C_cat != "NA") %>%
    ggplot() + geom_raster(aes(y = y, x = x, fill = freq_4C_cat)) + geom_polygon(data = world_spdf,
    aes(x = long, y = lat, group = group), colour = "#64686b", fill = NA, size = 0.1) +
    scale_fill_manual(values = c("#67001F", "#B2182B", "#D6604D", "#F4A582", "#FDDBC7",
        "#FAE9DF", "#F7F7F7"), name = "Months", guide = guide_legend(reverse = TRUE,
        nrow = 1)) + theme_void() + ylab(NULL) + xlab(NULL) + ggtitle("Mean drought frequency (+4°C)") +
    scale_y_continuous(limits = c(-60, 90), expand = c(0, 0)) + scale_x_continuous(limits = c(-180,
    180), expand = c(0, 0)) + theme(axis.title = element_blank(), axis.text = element_blank(),
    axis.ticks = element_blank(), plot.title = element_text(size = 10), legend.title = element_text(size = 8),
    legend.key.height = unit(0.2, "cm"), legend.key.width = unit(0.2, "cm"), legend.position = "bottom") +
    coord_fixed(ratio = 1)  # fixed ratio

freq_legend <- cowplot::get_legend(freq_4C_plot)

freq_prow <- cowplot::plot_grid(freq_cur_plot + theme(legend.position = "none"),
    freq_2C_plot + theme(legend.position = "none"), freq_4C_plot + theme(legend.position = "none"),
    align = "v", ncol = 3, labels = c("d", "e", "f"))

freq_plots <- cowplot::plot_grid(freq_prow, freq_legend, ncol = 1, rel_heights = c(1,
    0.1))


# Duration
dur_cur_plot <- PDSI_ab_df %>%
    dplyr::mutate(dur_cur_cat = case_when(dur_cur >= 2 & dur_cur < 4 ~ "2-4", dur_cur >=
        1 & dur_cur < 2 ~ "1-2", dur_cur > 0.1 & dur_cur < 1 ~ "<1")) %>%
    dplyr::mutate(dur_cur_cat = factor(dur_cur_cat, levels = c("2-4", "1-2", "<1"),
        ordered = TRUE)) %>%
    filter(dur_cur_cat != "NA") %>%
    ggplot() + geom_raster(aes(y = y, x = x, fill = dur_cur_cat)) + geom_polygon(data = world_spdf,
    aes(x = long, y = lat, group = group), colour = "#64686b", fill = NA, size = 0.1) +
    scale_fill_manual(values = c("#FDDBC7", "#FAE9DF", "#F7F7F7")) + theme_void() +
    ylab(NULL) + xlab(NULL) + ggtitle("Mean drought duration (1970–2000)") + scale_y_continuous(limits = c(-60,
    90), expand = c(0, 0)) + scale_x_continuous(limits = c(-180, 180), expand = c(0,
    0)) + theme(axis.title = element_blank(), axis.text = element_blank(), axis.ticks = element_blank(),
    plot.title = element_text(size = 10)) + coord_fixed(ratio = 1)  # fixed ratio

dur_2C_plot <- PDSI_ab_df %>%
    dplyr::mutate(dur_2C_cat = case_when(dur_2C >= 10 ~ ">10", dur_2C >= 8 & dur_2C <
        10 ~ "8-10", dur_2C >= 6 & dur_2C < 8 ~ "6-8", dur_2C >= 4 & dur_2C < 6 ~
        "4-6", dur_2C >= 2 & dur_2C < 4 ~ "2-4", dur_2C >= 1 & dur_2C < 2 ~ "1-2",
        dur_2C > 0.1 & dur_2C < 1 ~ "<1")) %>%
    dplyr::mutate(dur_2C_cat = factor(dur_2C_cat, levels = c(">10", "8-10", "6-8",
        "4-6", "2-4", "1-2", "<1"), ordered = TRUE)) %>%
    filter(dur_2C_cat != "NA") %>%
    ggplot() + geom_raster(aes(y = y, x = x, fill = dur_2C_cat)) + geom_polygon(data = world_spdf,
    aes(x = long, y = lat, group = group), colour = "#64686b", fill = NA, size = 0.1) +
    scale_fill_manual(values = c("#67001F", "#B2182B", "#D6604D", "#F4A582", "#FDDBC7",
        "#FAE9DF", "#F7F7F7")) + theme_void() + ylab(NULL) + xlab(NULL) + ggtitle("Mean drought duration (+2°C)") +
    scale_y_continuous(limits = c(-60, 90), expand = c(0, 0)) + scale_x_continuous(limits = c(-180,
    180), expand = c(0, 0)) + theme(axis.title = element_blank(), axis.text = element_blank(),
    axis.ticks = element_blank(), plot.title = element_text(size = 10)) + coord_fixed(ratio = 1)  # fixed ratio

dur_4C_plot <- PDSI_ab_df %>%
    dplyr::mutate(dur_4C_cat = case_when(dur_4C >= 10 ~ ">10", dur_4C >= 8 & dur_4C <
        10 ~ "8-10", dur_4C >= 6 & dur_4C < 8 ~ "6-8", dur_4C >= 4 & dur_4C < 6 ~
        "4-6", dur_4C >= 2 & dur_4C < 4 ~ "2-4", dur_4C >= 1 & dur_4C < 4 ~ "1-2",
        dur_4C > 0.1 & dur_4C < 1 ~ "<1")) %>%
    dplyr::mutate(dur_4C_cat = factor(dur_4C_cat, levels = c(">10", "8-10", "6-8",
        "4-6", "2-4", "1-2", "<1"), ordered = TRUE)) %>%
    filter(dur_4C_cat != "NA") %>%
    ggplot() + geom_raster(aes(y = y, x = x, fill = dur_4C_cat)) + geom_polygon(data = world_spdf,
    aes(x = long, y = lat, group = group), colour = "#64686b", fill = NA, size = 0.1) +
    scale_fill_manual(values = c("#67001F", "#B2182B", "#D6604D", "#F4A582", "#FDDBC7",
        "#FAE9DF", "#F7F7F7"), name = "Months", guide = guide_legend(reverse = TRUE,
        nrow = 1)) + theme_void() + ylab(NULL) + xlab(NULL) + ggtitle("Mean drought duration (+4°C)") +
    scale_y_continuous(limits = c(-60, 90), expand = c(0, 0)) + scale_x_continuous(limits = c(-180,
    180), expand = c(0, 0)) + theme(axis.title = element_blank(), axis.text = element_blank(),
    axis.ticks = element_blank(), plot.title = element_text(size = 10), legend.title = element_text(size = 8),
    legend.key.size = unit(0.2, "cm"), legend.position = "bottom") + coord_fixed(ratio = 1)  # fixed ratio

dur_legend <- cowplot::get_legend(dur_4C_plot)

dur_prow <- cowplot::plot_grid(dur_cur_plot + theme(legend.position = "none"), dur_2C_plot +
    theme(legend.position = "none"), dur_4C_plot + theme(legend.position = "none"),
    align = "v", ncol = 3, labels = c("g", "h", "i"))

dur_plots <- cowplot::plot_grid(dur_prow, dur_legend, ncol = 1, rel_heights = c(1,
    0.1))


cowplot::plot_grid(int_plots, freq_plots, dur_plots, ncol = 1)

Fig. S2. Mean monthly Palmer Drought Severity Index (PDSI) self-calibrated with Penman–Monteith potential evapotranspiration from (a) 1970–2000, and from 2080-2100 under (b) under an intermediate emission scenario (Shared Socioeconomic Pathways 2 - 4.5; SSP2-4.5), and (c) under a high emission scenario (SSP5-8.5). Mean yearly frequency of moderate to extreme drought (PDSI < -2) from (d) 1970–2000, and from 2080-2100 (e) under an intermediate emission scenario (SSP2-4.5), and (f) under a high emission scenario (SSP5-8.5). Mean duration of moderate to extreme drought (PDSI < -2) from (g) 1970–2000, and from 2080-2100 (h) under an intermediate emission scenario (SSP2-4.5), and (i) under a high emission scenario (SSP5-8.5).

Summary

Ecotype AI distribution

Mean ± s.d. aridity index occupied by different anuran ecotypes.

Ecotype AI (mean ± s.d.)
Stream-dwelling 1.46 ± 0.62
Arboreal 1.01 ± 0.62
Semi-aquatic 1.01 ± 0.58
Aquatic 0.98 ± 0.61
Ground-dwelling 0.89 ± 0.64
Fossorial 0.80 ± 0.61

2°C AI risk

Percent change in aridity by 2080–2100 (+ 2°C) relative to current climate (1981–2010) for all anurans and by ecotype.

Ecotype All (%) Aquatic 2°C (%) Arboreal 2°C (%) Fossorial 2°C(%) Ground-dwelling 2°C (%) Semi-aquatic 2°C (%) Stream-dwelling 2°C (%)
Hyper-arid -2.3 13.1 -15.2 -37.25 -2.0 4.7 -18.2
Arid 5.0 10.2 6.3 9.90 4.9 10.0 26.8
Semi-arid 1.4 2.1 1.5 0.75 1.6 1.1 13.9
Dry sub-humid 2.5 11.1 9.5 -3.67 8.4 2.8 10.4
Humid -1.4 -3.2 -2.2 -2.00 -2.4 -1.3 -1.3

4°C AI risk

Percent change in aridity by 2080–2100 (+ 4°C) relative to current climate (1981–2010) for all anurans and by ecotype.

Ecotype All (%) Aquatic 2°C (%) Arboreal 2°C (%) Fossorial 2°C(%) Ground-dwelling 2°C (%) Semi-aquatic 2°C (%) Stream-dwelling 2°C (%)
Hyper-arid 3.0 28.3 -4.3 -13.7 3.1 11.6 -9.1
Arid 13.2 33.0 20.6 23.1 13.5 27.0 43.7
Semi-arid 8.4 11.6 14.3 4.5 8.8 10.8 53.8
Dry sub-humid 9.0 25.2 16.6 -3.5 16.0 11.6 23.9
Humid -5.8 -9.8 -7.6 -7.5 -7.6 -5.7 -3.8

2°C PDSI risk

Percent change in drought intensity (ΔPDSI), frequency (ΔFrequency), and duration (ΔDuration) by 2080–2099 (+ 2°C scenario) relative to current climate (1970–2000) in grid cells occupied by anurans and by ecotype.

ΔPDSI All (%) Aquatic (%) Arboreal (%) Fossorial (%) Ground-dwelling (%) Semi-aquatic (%) Stream-dwelling (%)
-4 0.01 0.00 0.00 0.00 0.00 0.01 0.00
-3 0.15 0.00 0.00 0.00 0.06 0.19 0.00
-2 2.00 4.22 3.35 4.35 2.18 2.46 5.48
-1 18.55 33.52 28.74 27.06 20.99 21.74 26.88
0 71.05 54.90 55.68 54.07 68.60 66.72 60.07
1 6.40 5.19 8.86 9.94 6.05 6.84 6.19
2 1.59 1.83 2.90 3.99 1.84 1.74 1.23
3 0.25 0.34 0.48 0.59 0.29 0.30 0.14
ΔFrequency (months) All (%) Aquatic (%) Arboreal (%) Fossorial (%) Ground-dwelling (%) Semi-aquatic (%) Stream-dwelling (%)
10-12 0.14 0.00 0.00 0.00 0.05 0.17 0.00
8-10 0.22 0.03 0.06 0.03 0.18 0.25 0.20
6-8 0.61 0.78 0.70 0.79 0.60 0.70 0.86
4-6 2.15 3.86 3.40 3.01 2.33 2.26 3.71
2-4 12.25 21.14 19.23 16.82 13.42 13.75 26.57
1-2 16.90 24.28 17.56 18.39 18.51 18.26 10.49
0-1 56.26 42.56 46.21 46.64 53.17 54.34 48.46
-0-1 11.45 7.36 12.84 14.32 11.73 10.27 9.72
ΔDuration (months) All (%) Aquatic (%) Arboreal (%) Fossorial (%) Ground-dwelling (%) Semi-aquatic (%) Stream-dwelling (%)
>10 0.27 0.00 0.00 0.00 0.10 0.34 0.00
8-10 0.06 0.00 0.00 0.00 0.04 0.06 0.01
6-8 0.11 0.00 0.00 0.00 0.09 0.11 0.07
4-6 0.47 0.67 0.61 0.75 0.48 0.55 0.57
2-4 7.79 14.23 11.94 10.29 8.61 9.21 15.78
1-2 38.11 34.96 29.11 23.85 38.14 39.87 27.17
0-1 39.57 41.03 42.90 47.79 38.34 37.31 44.53
-0-1 12.98 8.46 14.49 16.04 13.47 11.90 11.82
-1-2 0.64 0.65 0.95 1.28 0.71 0.64 0.04

4°C PDSI risk

Percent change in drought intensity (ΔPDSI), frequency (ΔFrequency), and duration (ΔDuration) by 2080–2099 (+ 4°C scenario) relative to current climate (1970–2000) in grid cells occupied by anurans and by ecotype.

ΔPDSI All (%) Aquatic (%) Arboreal (%) Fossorial (%) Ground-dwelling (%) Semi-aquatic (%) Stream-dwelling (%)
-4 0.83 1.3 0.96 1.3 0.74 1.0 1.9
-3 4.44 9.9 7.80 9.6 5.04 5.4 15.2
-2 10.88 17.7 16.15 11.0 12.26 12.6 14.4
-1 22.33 26.6 19.04 25.3 24.78 23.6 12.2
0 44.62 31.9 37.41 32.8 42.33 40.2 41.6
1 9.63 4.5 6.79 5.6 6.97 9.5 6.8
2 2.94 2.2 4.17 4.3 2.87 2.9 3.4
3 1.39 1.9 2.30 2.4 1.60 1.4 1.9
4 2.94 3.9 5.38 7.7 3.41 3.4 2.5
ΔFrequency (months) All (%) Aquatic (%) Arboreal (%) Fossorial (%) Ground-dwelling (%) Semi-aquatic (%) Stream-dwelling (%)
10-12 1.6 2.2 1.9 2.0 1.6 1.9 2.9
8-10 4.9 9.3 7.7 7.3 5.4 5.3 11.6
6-8 7.0 10.9 10.0 8.4 7.8 7.5 11.9
4-6 14.0 17.1 13.2 9.9 15.7 15.4 10.7
2-4 22.8 22.8 17.9 25.1 24.1 22.9 12.4
1-2 12.1 11.2 12.9 12.1 11.4 11.4 16.2
0-1 30.1 20.3 26.5 22.8 25.6 28.4 29.4
-0-1 7.6 6.2 9.8 12.3 8.4 7.2 4.8
ΔDuration (months) All (%) Aquatic (%) Arboreal (%) Fossorial (%) Ground-dwelling (%) Semi-aquatic (%) Stream-dwelling (%)
>10 2.53 2.8 2.6 2.6 2.46 2.84 3.90
8-10 1.02 2.0 1.6 1.6 1.14 1.14 2.16
6-8 2.33 4.0 3.7 3.1 2.60 2.50 4.47
4-6 11.07 16.6 13.5 9.0 12.48 12.55 14.75
2-4 24.82 23.0 19.5 18.4 26.38 26.19 17.99
1-2 23.42 22.9 20.5 23.1 20.52 22.95 19.89
0-1 25.18 21.7 26.0 26.7 23.70 22.79 29.51
-0-1 8.83 5.8 11.0 13.5 9.79 8.12 7.27
-1-2 0.81 1.2 1.4 1.9 0.93 0.93 0.05

Dataset

# Load and clean raw data
raw_dat <- read.csv(file.path(data_path, "raw_data.csv")) %>%
  dplyr::select(study_ID:unit) %>%
  dplyr::mutate(ecotype  = factor(ecotype),
         family   = factor(family),
         origin   = factor(origin),
         strategy = factor(case_when(strategy == "" ~ "none", TRUE ~ as.character(strategy))),
         strategy = fct_relevel(strategy, "none", "water-proof", "cocoon", "hollow"),
         trait    = factor(trait),
         response = factor(response),
         lnMass   = log(mean_mass_g),
         lnFlow   = log(airflow_cm_s + 1),
         es_kPa   = ifelse(trait == "water loss", 0.611 * exp(2500000 / 461.5 * (1 / 273 - 1 / (trt_temp + 273.15))), NA), # saturation vapor pressure (kPa) at a given temperature
         ea_kPa   = ifelse(trait == "water loss", RH_perc * es_kPa / 100, NA), # actual vapor pressure (kPa)
         VPD_kPa  = es_kPa - ea_kPa,
         lnVPD    = log(VPD_kPa)) %>%
  dplyr::filter(species_phylo != "") # remove rows with no species

ewl_dat <- raw_dat %>%
  dplyr::filter(response == "evaporative water loss" & !is.na(unit_corrected_mean)) %>%
  dplyr::mutate(mg_h_mean = unit_corrected_mean * dors_SA_cm2,
                mg_h_sd   = unit_corrected_sd * dors_SA_cm2,    
                lnMean    = log(mg_h_mean),
                v         = mg_h_sd^2 / sample_size, # sampling variance (v)
                sei       = sqrt(v), # standard error (SE)
                inv       = 1 / sei, # precision (inverse of SE) )
                w         = 1 / v, # weight (inverse of variance) 
                h_70      = (mean_mass_g - (mean_mass_g * 0.7)) / (mg_h_mean * 0.001)) 

resist_dat <- raw_dat %>%
  dplyr::filter(unit == "s cm" & !is.na(unit_corrected_mean))

wu_dat <- raw_dat %>%
  dplyr::filter(response == "water uptake" & !is.na(unit_corrected_mean)) %>%
  dplyr::mutate(mg_h_mean = unit_corrected_mean * vent_SA_cm2,
                mg_h_sd   = unit_corrected_sd * vent_SA_cm2,
                lnMean    = log(mg_h_mean),
                v         = mg_h_sd^2 / sample_size, # sampling variance (v)
                sei       = sqrt(v), # standard error (SE)
                inv       = 1 / sei) # precision (inverse of SE)

#ewl_dat %>%
  #group_by(strategy) %>%
  #summarise(mean = mean(h_70, na.rm = TRUE))

There are 238 species with data on evaporative water loss (102 studies), 145 species with skin resistance data (43 studies), and 121 species with water uptake data (51 studies). We used the evaporative water loss to analyse differences between ecotype as there are more species represented compared to the skin resistance data. There were three species that were excluded from the analysis because they were not listed in the IUCN Red List and were not present in the phylogenetic tree from Jetz and Pyron (2018): Brachycephalus pitanga, Elachistocleis cesarii, and Leptodactylus luctator.

Geographical bias in hydroregulation studies

Fig. S4. Spatial distribution of hydroregulation studies using wild caught anurans (study n = 113). 19 studies used captive raised anurans. There are large regions around central Africa and Eurasia with high amphibian diversity, but no hydrological studies conducted (Fig. 1b).


Prepare phylogeny for analysis

The phylogeny was obtained from Jetz and Pyron (2018) comprising of 7,238 species. The tree was pruned to match the species extracted for the subsequent analysis.

# Load tree
phylo_tree <- ape::read.tree(file.path(data_path, "amph_shl_new_Consensus_7238.tre"))

# Pruning data and phylogeny
tree_tip_label <- phylo_tree$tip.label  # extract tree tip names
sp_list <- raw_dat$species_phylo  # extract species name from mean data
pruned_tree <- ape::drop.tip(phylo_tree, setdiff(phylo_tree$tip.label, sp_list))  # prune phylo_tree to keep species from the raw data
pruned_tree <- phytools::force.ultrametric(pruned_tree, method = "extend")  # ultrametricize the tree
phylo_cor <- vcv(pruned_tree, cor = T)

setdiff(raw_dat$species_phylo, rownames(phylo_cor))
setdiff(rownames(phylo_cor), raw_dat$species_phylo)

# ape::is.ultrametric(pruned_tree)

Analysis

The original model incorporated origin (lab-raised or wild-caught) and whether the bladder was void of urine prior to the experiment. However, the model’s bulk effective samples size (ESS) was too low, indicating posterior means and medians may be unreliable. Since origin and whether the bladder was emptied did not influence EWL, they were excluded in the final model. For transparency, on average, wild-caught anurans had, on average, lower EWL relative to lab-raised anurans (-0.08 [-0.47:0.31]), and anurans with their bladder voided of urine had lower EWL (-0.17 [-0.59: 0.25]). However there is substantial variability between the wild-caught and lab-raised groups, and whether anurans with their bladder voided or not.

# options(brms.backend = 'cmdstanr') # Error from using Rstans 'error in
# unserialize(socklist[[n]]) : error reading from connection'. Used cmdstanr
# around it.

priors <- c(prior(normal(0, 3), "b"), prior(normal(0, 3), "Intercept"), prior(student_t(3,
    0, 10), "sd"), prior(student_t(3, 0, 10), "sigma"))

ewl_model <- brms::brm(lnMean ~ ecotype + strategy + lnMass + lnVPD + lnFlow + (1 |
    study_ID) + (1 + lnMass | species_iucn) + (1 | gr(species_phylo, cov = phylo)),
    data = ewl_dat, family = gaussian(), data2 = list(phylo = phylo_cor), prior = priors,
    chains = 4, cores = 4, iter = 5000, warmup = 2500, control = list(adapt_delta = 0.99,
        max_treedepth = 15))

wu_model <- brms::brm(lnMean ~ ecotype + lnMass + trt_temp + hydration + origin +
    (1 | study_ID) + (1 + lnMass | species_iucn) + (1 | gr(species_phylo, cov = phylo)),
    data = wu_dat %>%
        dplyr::group_by(ecotype) %>%
        dplyr::filter(n() >= 5), family = gaussian(), data2 = list(phylo = phylo_cor),
    prior = priors, chains = 4, cores = 4, iter = 5000, warmup = 2500, control = list(adapt_delta = 0.99,
        max_treedepth = 15))

Fig. S5. Scatterplots of the observed data (y) vs the average simulated data (yrep) from the posterior predictive distribution for the (a) evaporative water loss model, and (b) the water uptake model. Dashed line represents a slope of 1.

Model output

Table S3 - EWL model

Table S3. Mean parameter estimates, estimate error, and 95% Bayesian credible intervals for the evaporative water loss model, which includes the intercept (\(\beta_0\)), ecotype, strategy, the natural logarithm of body mass (lnMass), the natural logarithm of vapour pressure deficit (lnVPD), and the natural logarithm of the experimental flow rate (lnFlow). Group-level effects include the standard deviations (\(\sigma\)) for study-level observations (\(\sigma_{study}^2\)), phylogenetic relatedness (\(\sigma_{phylogeny}^2\)), and the correlation among species (\(\sigma_{species}^2\)) and body mass (\(\sigma_{lnMass}^2\)). \(R_{marginal}^2\) represents the variance explained by fixed effects, while \(R_{conditional}^2\) represents the variance explained by both fixed effects and group-level effects.

Parameter Estimate Est.Error Q2.5 Q97.5
Fixed effects
ln\(\beta_0\) 3.76 0.52 2.71 4.79
Arboreal -0.40 0.53 -1.45 0.62
Fossorial -0.01 0.53 -1.06 1.00
Ground-dwelling -0.08 0.52 -1.12 0.94
Semi-aquatic 0.06 0.52 -0.99 1.06
Stream-dwelling 0.20 0.55 -0.90 1.28
Water-proof -1.77 0.16 -2.08 -1.46
Cocoon -1.83 0.13 -2.09 -1.58
Hollow -1.99 0.35 -2.68 -1.29
lnMass 0.55 0.03 0.49 0.61
lnVPD 0.29 0.05 0.19 0.39
lnFlow 0.33 0.06 0.21 0.46
Group-level effects
\(\sigma_{species}^2\) 0.10 0.07 0.00 0.26
\(\sigma_{lnMass}^2\) 0.07 0.03 0.01 0.13
cor(\(\sigma_{species}^2\), \(\sigma_{lnMass}^2\)) -0.09 0.57 -0.95 0.94
\(\sigma_{phylogeny}^2\) 0.39 0.08 0.23 0.55
\(\sigma_{study}^2\) 0.92 0.08 0.78 1.10
Phylogenetic signal
\(\lambda\) 0.42 0.11 0.19 0.61
Variance
\(R_{marginal}^2\) 64.07 60.14 67.39
\(R_{conditional}^2\) 91.97 90.92 92.87

Table S4 - WU model

Table S4. Mean parameter estimates, estimate error, and 95% Bayesian credible intervals for the water uptake model, which includes the intercept (\(\beta_0\)), ecotype, the natural logarithm of body mass (lnMass), treatment temperature, initial hydration level, and origin (lab-raised or wild caught). Group-level effects include the standard deviations (\(\sigma\)) for study-level observations (\(\sigma_{study}^2\)), phylogenetic relatedness (\(\sigma_{phylogeny}^2\)), and the correlation among species (\(\sigma_{species}^2\)) and body mass (\(\sigma_{lnMass}^2\)). \(R_{marginal}^2\) represents the variance explained by fixed effects, while \(R_{conditional}^2\) represents the variance explained by both fixed effects and group-level effects.

Parameter Estimate Est.Error Q2.5 Q97.5
Fixed effects
ln\(\beta_0\) 8.89 0.85 7.24 10.54
Fossorial -0.42 0.29 -1.00 0.14
Ground-dwelling -0.18 0.22 -0.62 0.24
Semi-aquatic -0.16 0.29 -0.71 0.42
ecotypeStream-dwelling -0.62 0.31 -1.22 -0.02
lnMass 0.80 0.05 0.70 0.90
Treatment temperature 0.01 0.01 -0.01 0.04
Initial hydration -0.05 0.01 -0.07 -0.04
Origin - Wild 0.03 0.43 -0.80 0.88
Group-level effects
\(\sigma_{species}^2\) 0.24 0.14 0.01 0.52
\(\sigma_{lnMass}^2\) 0.09 0.05 0.01 0.20
cor(\(\sigma_{species}^2\), \(\sigma_{lnMass}^2\)) 0.10 0.54 -0.89 0.96
\(\sigma_{phylogeny}^2\) 0.58 0.19 0.18 0.95
\(\sigma_{study}^2\) 1.03 0.13 0.80 1.32
Phylogenetic signal
\(\lambda\) 0.77 0.16 0.28 0.94
Variance
\(R_{marginal}^2\) 69.80 62.86 74.97
\(R_{conditional}^2\) 97.72 96.55 98.60

Fig. S6 - EWL model

Fig. S6. Differences in evaporative water loss (mg H2O h-1) by (a) ecotype and (b) water-conserving strategies. Note, when plotting by ecotype, the evaporative loss excludes behavioural water-conserving strategies such as during cocoon-forming and inside hollows. Mean estimates ± 95% CI presented in black points and error bars, while raw values were presented as grey points. The size of the grey points indicates study precision (inverse of standard error).

Fig. S7 - WU model

Fig. S7. Differences in cutaneous water uptake (mg H2O h-1) by ecotype. Mean estimates ± 95% CI presented in black points and error bars, while raw values were presented as grey points. The size of the grey points indicates study precision (inverse of standard error).


NicheMapR

To estimate the influence of warming and drought on activity of a hypothetical frog, we simulated a water and heat energy exchange model (Fig. S8a) and its interaction with a simulated local microclimate using the NicheMapR package (Kearney and Porter, 2017; Kearney and Porter, 2020).

Fig. S8. Summary water and energy exchange model from Tracy (1976) integrated into NicheMapR and water conserving strategies. (a) Schematic summary of the exchanges of energy and water between a frog and its environment used to develop the transient-state model of water exchange. In respect to water exchange, the net water loss represents water loss from respiratory, cutaneous, ocular, and cloaca evaporation as well as urinary and faecal water (Pirtle et al., 2019). (b) Behavioural, morphological, and physiological strategies employed by frogs on land to reduce water loss (Hillman et al., 2009).

Simulate water-conserving behaviours

We modified the current ectoR_devel function from NicheMapR v3.2.1 to account for the influence of hydration on activity (behav_functions function) which can be found in the behav_functions.R file on GitHub.

Ask Urtzi to elaborate and modify this section what was changed and what it represents

When the animal is not active (i.e. is below ground), it is simulated to go to an underground retreat. It selects the shallowest depth with temperatures between Tmax and Tmin. If water = T, the frog selects the shallowest node with temperatures between Tmax and Tmin and a water potential >= -72.5, which was reported as a soil water potential from which Rana pipiens could absorb water. When the animal is belowground, it re-hydrates at a rate specified in hyd.rate, if the soil water potential is >= -72.5. Important to note that currently frogs are not re-hydrating when active aboveground.

The “skinwet” term (\(p_{wet}\)) determines the proportion of the total surface area used in the calculation of mass transfer of water from the surface. Here, \(p_{wet}\) was calculated from empirically derived skin resistance following Pirtle et al. (2019):

\[\begin{equation} p_{wet} = \frac{1}{h_D \times r_i + (\frac{P_r}{S_c})^\frac{2}{3}}, \tag{16} \end{equation}\]

where \(r_i\) is the skin’s resistance to water vapor transfer (s m-1), \(P_r\) is the Prandtl number (dimensionless), \(S_c\) is the Schmidt number (dimensionless), \(h_D\) is the mass transfer coefficient (m s-1). To calculate \(p_{wet}\), the mass transfer coefficient (\(h_D\)) must be known. Mass transfer refers to the movement of a substance though a fluid interface, driven by changes in the concentration gradient. The mass transfer coefficient controls the rate of diffusion and is dependent on velocity, temperature, and physical properties of the interphase. Similar to the heat transfer coefficient, the mass transfer coefficient also has two components derived from free and forced convection. We consider forced convection only (as free convention should be negligible within a measurement chamber), and this can be calculated from the heat transfer coefficient:

\[\begin{equation} h_D = (\frac{h_C}{C_p \times \rho}) \times (\frac{P_r}{S_c}) ^ \frac{2}{3}, \tag{17} \end{equation}\]

where \(P_r\) is the Prandtl number (dimensionless), \(S_c\) is the Schmidt number (dimensionless), \(h_C\) is the heat transfer coefficient (J s-1 cm-2 K-1), \(\rho\) is the density of dry air (g cm-3), and \(C_p\) is the specific heat of air (1.01 J g-1 K-1).

Simulate drought and warming

Microclimates represent the physical environments experienced by an organism. They are a necessity for mechanistic niche modelling because it is the environment experienced at the scale of the individual that needs to be provided to the equations of energy and mass balance. The microclimate model was implemented as described by Kearney et al. (2014). Specifically, it was driven by historical 0.05° grid (~5 km) daily weather input layers (air temperature, vapor pressure, wind speed, and cloud cover).

We simulated meteorological drought (defined as less than average rainfall) by modifying the micro_era5 function from NicheMapR to incorporate rainfall (rainfact) and relative humidity (rhfact) deficit factors. A default factor is 1 which is 100% of the original rainfall or relative humidity. A factor of 0.5 means 50% of the original rainfall or relative humidity. The modified function can be found on the accompanying GitHub page.

To simulate frog activity under drought and warming scenarios, we constructed four climate conditions using the micro_era5 function:

  1. current normal scenario representing the mean annual air temperature and rainfall from 1981–2010,
  2. current drought scenario representing the mean annual air temperature from 1981-2010 and annual rainfall based on 2017-2019 drought in Australia (Fig. S9),
  3. warming normal scenario representing the “business-as-usual” scenario, where the global surface temperature is estimated to increase by 4°C by 2080–2100 with no effect of drought (+4°C only), and
  4. warming drought scenario with a +4°C increasing in air temperature and annual rainfall based on 2017-2019 drought in Australia.

First, download the mcera5 microclimate data to a local directory to run the micro_era5 function faster.

# get ERA5 data with package mcera5 assign your credentials (register here:
# https://cds.climate.copernicus.eu/user/register)
uid <- "$$$$$$"
cds_api_key <- "$$$$$$$$-$$$$-$$$$-$$$$-$$$$$$$$$$$$"
ecmwfr::wf_set_key(user = uid, key = cds_api_key, service = "cds")

# bounding coordinates (in WGS84 / EPSG:4326)
c(-41.19, -20.186)
xmn <- -42
xmx <- -41
ymn <- -21
ymx <- -20

xmn <- 152
xmx <- 154
ymn <- -28
ymx <- -26

# temporal extent
st_time <- lubridate::ymd("2016:01:01")  # earliest sampling date
en_time <- lubridate::ymd("2018:12:31")  # latest sampling date

# filename and location for downloaded .nc files
file_prefix <- "era5"
op <- "YOUR DIRECTORY"

# build a request (covering multiple years)
req <- mcera5::build_era5_request(xmin = xmn, xmax = xmx, ymin = ymn, ymax = ymx,
    start_time = st_time, end_time = en_time, outfile_name = file_prefix)

mcera5::request_era5(request = req, uid = uid, out_path = op)

Next, run the micro_era5 function for the four scenarios in 2017 (representing typical rainfall year), and one for 2019 to validate the observed rainfall data.

source("/Users/nicholaswu/Library/CloudStorage/OneDrive-WesternSydneyUniversity/Drought project/code/micro_era5_drought.R")

longlat <- c(153.09249, -27.6235) # Karawatha, QLD.

# Current normal 2017 scenario
micro_curr_wet <- micro_era5(loc = longlat, 
                             runshade = 1, minshade = 0, # shade parameters
                             rainfact = 1.2, rhfact = 1, # rain and RH parameters
                             warm = 0, # current climate
                             dstart = "01/01/2017", 
                             dfinish = "31/12/2017",
                             spatial = '/Users/nicholaswu/Library/CloudStorage/OneDrive-WesternSydneyUniversity/Drought project/Spatial data/karawatha/era5', # change to your location
                             save = 0)

# Current dry 2017 scenario
micro_curr_dry <- micro_era5(loc = longlat, 
                             runshade = 1, minshade = 0, # shade parameters
                             rainfact = 0.5, rhfact = 0.1, # rain and RH parameters
                             warm = 0, # current climate
                             dstart = "01/01/2017", 
                             dfinish = "31/12/2017",
                             spatial = '/Users/nicholaswu/Library/CloudStorage/OneDrive-WesternSydneyUniversity/Drought project/Spatial data/karawatha/era5', # change to your location
                             save = 0)

# Warming normal 2017 scenario
micro_warm_wet <- micro_era5(loc = longlat, 
                             runshade = 1, minshade = 0, # shade parameters
                             rainfact = 1.2, rhfact = 1, # rain and RH parameters
                              warm = 4, # future climate
                              dstart = "01/01/2017", 
                              dfinish = "31/12/2017",
                              spatial = '/Users/nicholaswu/Library/CloudStorage/OneDrive-WesternSydneyUniversity/Drought project/Spatial data/karawatha/era5', # change to your location
                              save = 0)

# Warming dry 2017 scenario (simulating 2019 drought)
micro_warm_dry <- micro_era5(loc = longlat, 
                             runshade = 1, minshade = 0, # shade parameters
                             rainfact = 0.5, rhfact = 0.1, # rain and RH parameters
                             warm = 4, # future climate
                             dstart = "01/01/2017", 
                             dfinish = "31/12/2017",
                             spatial = '/Users/nicholaswu/Library/CloudStorage/OneDrive-WesternSydneyUniversity/Drought project/Spatial data/karawatha/era5', # change to your location
                             save = 0)

# Simulate rainfall for 2019 drought
act_dry <- micro_era5(loc = longlat, 
                      runshade = 1, minshade = 0, # shade parameters
                      warm = 0, # current climate
                      dstart = "01/01/2019", 
                      dfinish = "31/12/2019",
                      spatial = '/Users/nicholaswu/Library/CloudStorage/OneDrive-WesternSydneyUniversity/Drought project/Spatial data/karawatha/era5', # change to your location
                      save = 0)

To verify our microclimate models, we plotted the simulated the daily rainfall for 2017 (representing typical rainfall) and 2019 (historical drought) with the observed daily rainfall in Australia for the following location: Karawatha, Southeast Queensland, Australia (153.09249, -27.6235). Karawatha provides a good case study because there are many ecotypes found in this location: ground-dwelling (e.g. Rhinella marina), arboreal (e.g. Litoria caerulea), fossorial (e.g. Cyclorana alboguttata), semi-aquatic (e.g. Litoria nasuta), and this area has experienced drought recently (2019). We extracted rainfall data from a weather station next to Karawatha which experienced “very much below average” rainfall from the Australian Bureau of Meteorology.

# Load observed rainfall for 2019
obs_rainfall <- read.csv(file.path(data_path, "obs_rainfall.csv")) %>%
    tibble::rowid_to_column("DOY") %>%
    dplyr::mutate(date = lubridate::make_date(year = 2019, month = month_num, day = day))

# Merge observed and predicted rainfall together

model_rain_wet <- as.data.frame(micro_curr_wet$RAINFALL) %>%
    tibble::rowid_to_column("DOY") %>%
    rename(rainfall_mm = "micro_curr_wet$RAINFALL") %>%
    merge(obs_rainfall, by = "DOY", all.x = TRUE)

model_2019 <- as.data.frame(act_dry$RAINFALL) %>%
    tibble::rowid_to_column("DOY") %>%
    rename(rainfall_mm = "act_dry$RAINFALL") %>%
    merge(obs_rainfall, by = "DOY", all.x = TRUE)

# 2019 drought validate
rain_dry_plot <- model_2019 %>%
    ggplot() + geom_line(aes(x = DOY, y = karawatha_19), colour = "grey") + geom_line(aes(x = DOY,
    y = rainfall_mm), colour = "red", alpha = 0.5) + labs(x = NULL, y = "Daily rainfall (mm)") +
    ggtitle("2019 Drought") + scale_y_continuous(lim = c(0, 100), expand = c(0, 0)) +
    scale_x_continuous(expand = c(0, 0)) + mytheme() + theme(legend.position = "bottom")

# 2017 normal validate
rain_wet_plot <- model_rain_wet %>%
    ggplot() + geom_line(aes(x = DOY, y = karawatha_17), colour = "grey") + geom_line(aes(x = DOY,
    y = rainfall_mm), colour = "red", alpha = 0.5) + labs(x = NULL, y = "Daily rainfall (mm)") +
    ggtitle("2017 Normal") + scale_y_continuous(lim = c(0, 100), expand = c(0, 0)) +
    scale_x_continuous(expand = c(0, 0)) + mytheme() + theme(legend.position = "bottom")

cowplot::plot_grid(rain_wet_plot, rain_dry_plot, ncol = 2)

Fig. S9. Simulated rainfall from the micro_era5 function (red) and the observed rainfall for Karawatha, QLD from the Australian Bureau of Meteorology (grey). The total yearly observed rainfall for 2017 was as 1100 mm, and the total simulated yearly rainfall from NicheMapR was 1097.12 mm. The total yearly observed rainfall for the 2019 drought was 598 mm, and the total simulated yearly rainfall from NicheMapR was 556.22 mm. The average yearly rainfall across 1981-2010 is around 1100 mm per year.

Simulate activity

We simulated the potential number of hours for activity in a year (\(t_{act}\)) which represents the suitable thermal and hydric conditions for the animal to move beyond their retreat to either catch prey or finding mates (Kearney and Porter, 2020). The thermoregulatory and hydroregulatory sequence in the model assumes that frogs will only be ‘active’ (i.e. moving beyond their retreat, catching prey, finding mates) between the minimum and maximum body temperature thresholds for foraging, Tmin and Tmax (°C), and the minimum tolerated hydration, min.hyd (%). In addition, if water.act = T, the frog will only be active if temperatures are within the suitable temp range, and the frog is not expected to go below allowed hydration levels (e.g. if %hydration is not below min.hyd).

To estimate the potential \(t_{act}\) for one year, we simulated the hypothetical frog to be active during the day and night (24 hours). While most frogs are nocturnal, there are some frog species found moving during the day. The water hydric parameters (e.g. skin resistance, water uptake rate, dehydration tolerance) were based on the average values of the dataset collected from the PRISMA search. The thermal parameters (minimum and maximum foraging and critical temperature) were based on Rhinalla marina which has been verified in Kearney et al. (2008).

Three water-saving strategies were constructed to broadly reflect each ecotype that use either behavioural strategies such as microhabitat selection, or physiological strategies such as increased skin resistance or skin thickness (Table S5). For example, many amphibians (espically arid specialist) seek or burrow underground to regulate body temperature and water balance without exhibiting thicker skin or higher skin resistance. This is because underground burrows are generally cooler, less varied temperature fluctuation, and more moist relative to the surface climate.

Table S5. Modified parameters for the sim.ecto function for each hypothetical frog model. The skin resistance values were based on the average empirical measurements for a typical frog and a waterproof frog in the meta-analysis. Seek shade represents microclimate simulated under shaded conditions (0-90% shade). Retreat underground represents the ability for the frog to seek suitable microclimates underground. Can climb represents the ability for the frog to seek suitable microclimates above ground level (e.g. trees, cliffs). Note, frogs are not active when underground, and water uptake only occurs during inactivity.

Water-saving strategy Skin resistance Seek shade? Retreat underground? Can climb? Ecotype
Shade only Low Yes No No Ground-dwelling
Waterproof High Yes No Yes Arboreal
Fossorial Low Yes Yes No Fossorial

It is important to note that we focus only on the direct effects of environmental change on water budgets by predicting changes in EWL rates. The conclusions we draw do not account for the indirect effects of environmental change on water budgets, such as potential changes to thermal tolerance as a result of dehydration, or the thermoregulatory difficulties that may arise as a result of habitat modification.

source("/Users/nicholaswu/Library/CloudStorage/OneDrive-WesternSydneyUniversity/Drought project/code/behav_functions.R")
# Construct frog model
# compute the heat exchange by convection (extract mass transfer coefficient, Prandtl number and Schmidt number)
CONV_out <- NicheMapR::CONV_ENDO(TS     = 19, # skin temperature (°C)
                                 TENV   = 20, # fluid temperature (°C)
                                 SHAPE  = 4, # 4 is ellipsoid
                                 SURFAR = mean(resist_dat$dors_SA_cm2, na.rm = TRUE) / 10000,  # surface area for convection, m2
                                 FLTYPE = 0, # fluid type: 0 = air
                                 FURTST = 0, # test of presence of fur (length x diameter x density x depth) (-)
                                 D      = mean(resist_dat$D, na.rm = TRUE), 
                                 TFA    = 20, # initial fur/air interface temperature
                                 VEL    = mean(resist_dat$airflow_cm_s, na.rm = TRUE) / 100, # wind speed (m/s)
                                 ZFUR   = 0, # fur depth, mean (m)
                                 BP     = 101325, # barometric pressure at sea level
                                 ELEV   = 0) # elevation (m)

# basic parameters for 30 g frog
Ww_g         <- exp(mean(log(raw_dat$mean_mass_g), na.rm = TRUE)) # geometric mean wet weight of animal (g), account for uneven distribution
r_s_low      <- resist_dat %>% dplyr::filter(strategy == "none") %>% dplyr::select(unit_corrected_mean) # skin resistance
pct_wet_high <- 1 / (CONV_out[5] * mean(r_s_low$unit_corrected_mean) + (CONV_out[11] / CONV_out[13]) ^ 0.6666666) * 100  # % of surface area acting as a free-water exchanger (Pirtle et al 2017)

# parameters for a water-proof frog
r_s_high    <- resist_dat %>% dplyr::filter(strategy == "water-proof") %>% dplyr::select(unit_corrected_mean) # skin resistance
pct_wet_low <- 1 / (CONV_out[5] * max(r_s_high$unit_corrected_mean) + (CONV_out[11] / CONV_out[13]) ^ 0.6666666) * 100 # % of surface area acting as a free-water exchanger (Pirtle et al 2017)

# Thermal traits based on Rhinella marina
Tmin   <- 13.7 # minimum Tb at which activity occurs (Kearney et al 2008)
Tmax   <- 30.4 # maximum Tb at which activity occurs (Kearney et al 2008)
#T_pref <- 24 # preferred Tb (Kearney et al 2008)
CTmax  <- 37 # critical thermal minimum (affects choice of retreat) Tracy et al 2012
CTmin  <- 8 # critical thermal maximum (affects choice of retreat) Kolbe et al 2010, McCann et al 2014

# Water balance traits
min_hyd <- 80 # minimum tolerated hydration before activity declines (% of fully hydrated animals)
hyd.death <- 50 # minimum tolerated hydration before death (% of fully hydrated animals)
wu_rate <- wu_dat %>% dplyr::filter(strategy == "none") %>% dplyr::select(mg_h_mean)
hyd_rate <- exp(mean(log(wu_rate$mg_h_mean), na.rm = TRUE)) / 1000 # geometric mean rehydration rate (g/h), account for uneven distribution
# depends on current and max hydration like this: hyd.rate * ((hyd - hyd.current) / hyd)

# behav = 'diurnal', 'nocturnal' or 'both'
# water; does the frog select depth according to water potential? (TRUE or FALSE)
# water.act; does the activity depend on water loss? (TRUE or FALSE)

# SHADE MODEL
shad_curr_wet_mod <- sim.ecto(micro_curr_wet, Ww_g = Ww_g, shape = 4, 
                              Tmax = Tmax, Tmin = Tmin, CTmin = CTmin, CTmax = CTmax,
                              behav = 'both', in.shade = TRUE, burrow = FALSE, climb = FALSE,
                              min.hyd = min_hyd, hyd.death = hyd.death,
                              hyd.rate = hyd_rate, pct_wet = pct_wet_high, 
                              water = FALSE, water.act = TRUE)

shad_curr_dry_mod <- sim.ecto(micro_curr_dry, Ww_g = Ww_g, shape = 4, 
                              Tmax = Tmax, Tmin = Tmin, CTmin = CTmin, CTmax = CTmax,
                              behav = 'both', in.shade = TRUE, burrow = FALSE, climb = FALSE,
                              min.hyd = min_hyd, hyd.death = hyd.death,
                              hyd.rate = hyd_rate, pct_wet = pct_wet_high, 
                              water = FALSE, water.act = TRUE)

shad_warm_wet_mod <- sim.ecto(micro_warm_wet, Ww_g = Ww_g, shape = 4, 
                              Tmax = Tmax, Tmin = Tmin, CTmin = CTmin, CTmax = CTmax,
                              behav = 'both', in.shade = TRUE, burrow = FALSE, climb = FALSE,
                              min.hyd = min_hyd, hyd.death = hyd.death,
                              hyd.rate = hyd_rate, pct_wet = pct_wet_high, 
                              water = FALSE, water.act = TRUE)

shad_warm_dry_mod <- sim.ecto(micro_warm_dry, Ww_g = Ww_g, shape = 4, 
                              Tmax = Tmax, Tmin = Tmin, CTmin = CTmin, CTmax = CTmax,
                              behav = 'both', in.shade = TRUE, burrow = FALSE, climb = FALSE,
                              min.hyd = min_hyd, hyd.death = hyd.death,
                              hyd.rate = hyd_rate, pct_wet = pct_wet_high, 
                              water = FALSE, water.act = TRUE)

# WATER-PROOF MODEL
tree_curr_wet_mod <- sim.ecto(micro_curr_wet, Ww_g = Ww_g, shape = 4, 
                              Tmax = Tmax, Tmin = Tmin, CTmin = CTmin, CTmax = CTmax,
                              behav = 'both', in.shade = TRUE, burrow = FALSE, climb = TRUE,
                              min.hyd = min_hyd, hyd.death = hyd.death,
                              hyd.rate = hyd_rate, pct_wet = pct_wet_low, 
                              water = TRUE, water.act = TRUE)

tree_curr_dry_mod <- sim.ecto(micro_curr_dry, Ww_g = Ww_g, shape = 4, 
                              Tmax = Tmax, Tmin = Tmin, CTmin = CTmin, CTmax = CTmax,
                              behav = 'both', in.shade = TRUE, burrow = FALSE, climb = TRUE,
                              min.hyd = min_hyd, hyd.death = hyd.death,
                              hyd.rate = hyd_rate, pct_wet = pct_wet_low, 
                              water = TRUE, water.act = TRUE)

tree_warm_wet_mod <- sim.ecto(micro_warm_wet, Ww_g = Ww_g, shape = 4, 
                              Tmax = Tmax, Tmin = Tmin, CTmin = CTmin, CTmax = CTmax,
                              behav = 'both', in.shade = TRUE, burrow = FALSE, climb = TRUE,
                              min.hyd = min_hyd, hyd.death = hyd.death,
                              hyd.rate = hyd_rate, pct_wet = pct_wet_low, 
                              water = TRUE, water.act = TRUE)

tree_warm_dry_mod <- sim.ecto(micro_warm_dry, Ww_g = Ww_g, shape = 4, 
                              Tmax = Tmax, Tmin = Tmin, CTmin = CTmin, CTmax = CTmax,
                              behav = 'both', in.shade = TRUE, burrow = FALSE, climb = TRUE,
                              min.hyd = min_hyd, hyd.death = hyd.death,
                              hyd.rate = hyd_rate, pct_wet = pct_wet_low, 
                              water = TRUE, water.act = TRUE)

# BURROWING MODEL
burr_curr_wet_mod <- sim.ecto(micro_curr_wet, Ww_g = Ww_g, shape = 4, 
                              Tmax = Tmax, Tmin = Tmin, CTmin = CTmin, CTmax = CTmax,
                              behav = 'both', in.shade = TRUE, burrow = TRUE, climb = FALSE,
                              min.hyd = min_hyd, hyd.death = hyd.death,
                              hyd.rate = hyd_rate, pct_wet = pct_wet_high, 
                              water = TRUE, water.act = TRUE)

burr_curr_dry_mod <- sim.ecto(micro_curr_dry, Ww_g = Ww_g, shape = 4, 
                              Tmax = Tmax, Tmin = Tmin, CTmin = CTmin, CTmax = CTmax,
                              behav = 'both', in.shade = TRUE, burrow = TRUE, climb = FALSE,
                              min.hyd = min_hyd, hyd.death = hyd.death,
                              hyd.rate = hyd_rate, pct_wet = pct_wet_high, 
                              water = TRUE, water.act = TRUE)

burr_warm_wet_mod <- sim.ecto(micro_warm_wet, Ww_g = Ww_g, shape = 4, 
                              Tmax = Tmax, Tmin = Tmin, CTmin = CTmin, CTmax = CTmax,
                              behav = 'both', in.shade = TRUE, burrow = TRUE, climb = FALSE,
                              min.hyd = min_hyd, hyd.death = hyd.death,
                              hyd.rate = hyd_rate, pct_wet = pct_wet_high, 
                              water = TRUE, water.act = TRUE)

burr_warm_dry_mod <- sim.ecto(micro_warm_dry, Ww_g = Ww_g, shape = 4, 
                              Tmax = Tmax, Tmin = Tmin, CTmin = CTmin, CTmax = CTmax,
                              behav = 'both', in.shade = TRUE, burrow = TRUE, climb = FALSE,
                              min.hyd = min_hyd, hyd.death = hyd.death,
                              hyd.rate = hyd_rate, pct_wet = pct_wet_high, 
                              water = TRUE, water.act = TRUE)
# SHADE MODEL
shad_curr_wet_df <- data.frame(shad_curr_wet_mod$act) %>%
    tibble::rowid_to_column("hour") %>%
    dplyr::rename(active = shad_curr_wet_mod.act) %>%
    dplyr::mutate(day = ceiling(1:8760/24)) %>%
    dplyr::group_by(day) %>%
    dplyr::summarise(curr_wet = length(active[active == TRUE]))

shad_curr_dry_df <- data.frame(shad_curr_dry_mod$act) %>%
    tibble::rowid_to_column("hour") %>%
    dplyr::rename(active = shad_curr_dry_mod.act) %>%
    dplyr::mutate(day = ceiling(1:8760/24)) %>%
    dplyr::group_by(day) %>%
    dplyr::summarise(curr_dry = length(active[active == TRUE]))

shad_warm_wet_df <- data.frame(shad_warm_wet_mod$act) %>%
    tibble::rowid_to_column("hour") %>%
    dplyr::rename(active = shad_warm_wet_mod.act) %>%
    dplyr::mutate(day = ceiling(1:8760/24)) %>%
    dplyr::group_by(day) %>%
    dplyr::summarise(warm_wet = length(active[active == TRUE]))

shad_warm_dry_df <- data.frame(shad_warm_dry_mod$act) %>%
    tibble::rowid_to_column("hour") %>%
    dplyr::rename(active = shad_warm_dry_mod.act) %>%
    dplyr::mutate(day = ceiling(1:8760/24)) %>%
    dplyr::group_by(day) %>%
    dplyr::summarise(warm_dry = length(active[active == TRUE]))

shad_model <- shad_curr_wet_df %>%
    merge(shad_curr_dry_df, by = "day") %>%
    merge(shad_warm_wet_df, by = "day") %>%
    merge(shad_warm_dry_df, by = "day") %>%
    pivot_longer(!day, names_to = "condition", values_to = "hours") %>%
    dplyr::mutate(condition = factor(condition, levels = c("warm_dry", "warm_wet",
        "curr_dry", "curr_wet")), season = case_when(day >= 335 ~ "summer", day >=
        1 & day <= 61 ~ "summer", day >= 62 & day <= 153 ~ "autumn", day >= 154 &
        day <= 244 ~ "winter", day >= 245 & day <= 334 ~ "spring"))

# TREE MODEL
tree_curr_wet_df <- data.frame(tree_curr_wet_mod$act) %>%
    tibble::rowid_to_column("hour") %>%
    dplyr::rename(active = tree_curr_wet_mod.act) %>%
    dplyr::mutate(day = ceiling(1:8760/24)) %>%
    dplyr::group_by(day) %>%
    dplyr::summarise(curr_wet = length(active[active == TRUE]))

tree_curr_dry_df <- data.frame(tree_curr_dry_mod$act) %>%
    tibble::rowid_to_column("hour") %>%
    dplyr::rename(active = tree_curr_dry_mod.act) %>%
    dplyr::mutate(day = ceiling(1:8760/24)) %>%
    dplyr::group_by(day) %>%
    dplyr::summarise(curr_dry = length(active[active == TRUE]))

tree_warm_wet_df <- data.frame(tree_warm_wet_mod$act) %>%
    tibble::rowid_to_column("hour") %>%
    dplyr::rename(active = tree_warm_wet_mod.act) %>%
    dplyr::mutate(day = ceiling(1:8760/24)) %>%
    dplyr::group_by(day) %>%
    dplyr::summarise(warm_wet = length(active[active == TRUE]))

tree_warm_dry_df <- data.frame(tree_warm_dry_mod$act) %>%
    tibble::rowid_to_column("hour") %>%
    dplyr::rename(active = tree_warm_dry_mod.act) %>%
    dplyr::mutate(day = ceiling(1:8760/24)) %>%
    dplyr::group_by(day) %>%
    dplyr::summarise(warm_dry = length(active[active == TRUE]))

tree_model <- tree_curr_wet_df %>%
    merge(tree_curr_dry_df, by = "day") %>%
    merge(tree_warm_wet_df, by = "day") %>%
    merge(tree_warm_dry_df, by = "day") %>%
    pivot_longer(!day, names_to = "condition", values_to = "hours") %>%
    dplyr::mutate(condition = factor(condition, levels = c("warm_dry", "warm_wet",
        "curr_dry", "curr_wet")), season = case_when(day >= 335 ~ "summer", day >=
        1 & day <= 61 ~ "summer", day >= 62 & day <= 153 ~ "autumn", day >= 154 &
        day <= 244 ~ "winter", day >= 245 & day <= 334 ~ "spring"))

# FOSSORIAL MODEL
burr_curr_wet_df <- data.frame(burr_curr_wet_mod$act) %>%
    tibble::rowid_to_column("hour") %>%
    dplyr::rename(active = burr_curr_wet_mod.act) %>%
    dplyr::mutate(day = ceiling(1:8760/24)) %>%
    dplyr::group_by(day) %>%
    dplyr::summarise(curr_wet = length(active[active == TRUE]))

burr_curr_dry_df <- data.frame(burr_curr_dry_mod$act) %>%
    tibble::rowid_to_column("hour") %>%
    dplyr::rename(active = burr_curr_dry_mod.act) %>%
    dplyr::mutate(day = ceiling(1:8760/24)) %>%
    dplyr::group_by(day) %>%
    dplyr::summarise(curr_dry = length(active[active == TRUE]))

burr_warm_wet_df <- data.frame(burr_warm_wet_mod$act) %>%
    tibble::rowid_to_column("hour") %>%
    dplyr::rename(active = burr_warm_wet_mod.act) %>%
    dplyr::mutate(day = ceiling(1:8760/24)) %>%
    dplyr::group_by(day) %>%
    dplyr::summarise(warm_wet = length(active[active == TRUE]))

burr_warm_dry_df <- data.frame(burr_warm_dry_mod$act) %>%
    tibble::rowid_to_column("hour") %>%
    dplyr::rename(active = burr_warm_dry_mod.act) %>%
    dplyr::mutate(day = ceiling(1:8760/24)) %>%
    dplyr::group_by(day) %>%
    dplyr::summarise(warm_dry = length(active[active == TRUE]))

burr_model <- burr_curr_wet_df %>%
    merge(burr_curr_dry_df, by = "day") %>%
    merge(burr_warm_wet_df, by = "day") %>%
    merge(burr_warm_dry_df, by = "day") %>%
    pivot_longer(!day, names_to = "condition", values_to = "hours") %>%
    dplyr::mutate(condition = factor(condition, levels = c("warm_dry", "warm_wet",
        "curr_dry", "curr_wet")), season = case_when(day >= 335 ~ "summer", day >=
        1 & day <= 61 ~ "summer", day >= 62 & day <= 153 ~ "autumn", day >= 154 &
        day <= 244 ~ "winter", day >= 245 & day <= 334 ~ "spring"))

Model output

Table S6a - Summary

Table S6a. Total potential activity hours per year (\(t_{act}\)) for a 8.73 g frog under different warming (current or warming) and drought (normal or drought) conditions with different water-saving strategies.

data.frame(strategy = c("Shade only", "Shade only", "Shade only", "Shade only", "Waterproof",
    "Waterproof", "Waterproof", "Waterproof", "Burrowing", "Burrowing", "Burrowing",
    "Burrowing"), temp = c("current", "current", "warming", "warming"), rain = c("normal",
    "drought"), t_act_h = c(sum(shad_curr_wet_df$curr_wet), sum(shad_curr_dry_df$curr_dry),
    sum(shad_warm_wet_df$warm_wet), sum(shad_warm_dry_df$warm_dry), sum(tree_curr_wet_df$curr_wet),
    sum(tree_curr_dry_df$curr_dry), sum(tree_warm_wet_df$warm_wet), sum(tree_warm_dry_df$warm_dry),
    sum(burr_curr_wet_df$curr_wet), sum(burr_curr_dry_df$curr_dry), sum(burr_warm_wet_df$warm_wet),
    sum(burr_warm_dry_df$warm_dry)), t_act_per = c(sum(shad_curr_wet_df$curr_wet)/8760 *
    100, sum(shad_curr_dry_df$curr_dry)/8760 * 100, sum(shad_warm_wet_df$warm_wet)/8760 *
    100, sum(shad_warm_dry_df$warm_dry)/8760 * 100, sum(tree_curr_wet_df$curr_wet)/8760 *
    100, sum(tree_curr_dry_df$curr_dry)/8760 * 100, sum(tree_warm_wet_df$warm_wet)/8760 *
    100, sum(tree_warm_dry_df$warm_dry)/8760 * 100, sum(burr_curr_wet_df$curr_wet)/8760 *
    100, sum(burr_curr_dry_df$curr_dry)/8760 * 100, sum(burr_warm_wet_df$warm_wet)/8760 *
    100, sum(burr_warm_dry_df$warm_dry)/8760 * 100)) %>%
    knitr::kable(col.names = c("Water-saving strategy", "Warming simulation", "Drought simulation",
        "$t_{act}$ (h)", "$t_{act}$ (%)"))
Water-saving strategy Warming simulation Drought simulation \(t_{act}\) (h) \(t_{act}\) (%)
Shade only current normal 3972 45
Shade only current drought 3798 43
Shade only warming normal 4318 49
Shade only warming drought 4099 47
Waterproof current normal 4634 53
Waterproof current drought 4442 51
Waterproof warming normal 4831 55
Waterproof warming drought 4587 52
Burrowing current normal 4287 49
Burrowing current drought 4190 48
Burrowing warming normal 4715 54
Burrowing warming drought 4594 52

Table S6b - Relative change year

Table S6b. Change in \(t_{act}\) (%) for each water-saving strategy relative to the current normal scenario under warming only, drought only, and warming and drought combined.

data.frame(strategy = c("Shade only", "Waterproof", "Burrowing"), curr_wet = c(sum(shad_curr_wet_df$curr_wet),
    sum(tree_curr_wet_df$curr_wet), sum(burr_curr_wet_df$curr_wet)), curr_dry = c(sum(shad_curr_dry_df$curr_dry),
    sum(tree_curr_dry_df$curr_dry), sum(burr_curr_dry_df$curr_dry)), warm_wet = c(sum(shad_warm_wet_df$warm_wet),
    sum(tree_warm_wet_df$warm_wet), sum(burr_warm_wet_df$warm_wet)), warm_dry = c(sum(shad_warm_dry_df$warm_dry),
    sum(tree_warm_dry_df$warm_dry), sum(burr_warm_dry_df$warm_dry))) %>%
    dplyr::mutate(delta_warm = (warm_wet - curr_wet)/curr_wet * 100, delta_dry = (curr_dry -
        curr_wet)/curr_wet * 100, delta_warm_dry = (warm_dry - curr_wet)/curr_wet *
        100) %>%
    dplyr::select(-c(curr_wet:warm_dry)) %>%
    knitr::kable(col.names = c("Water-saving strategy", "$\\Delta$ warming only (%)",
        "$\\Delta$ drought only (%)", "$\\Delta$ warming and drought (%)"))
Water-saving strategy \(\Delta\) warming only (%) \(\Delta\) drought only (%) \(\Delta\) warming and drought (%)
Shade only 8.7 -4.4 3.2
Waterproof 4.2 -4.1 -1.0
Burrowing 10.0 -2.3 7.2

Table S6c - Relative change season

Table S6c. Change in \(t_{act}\) (%) for each water-saving strategy relative to the current normal scenario under warming only, drought only, and warming and drought combined.

# summer
shad_model_summer <- shad_model %>%
    dplyr::filter(season == "summer") %>%
    dplyr::group_by(condition) %>%
    dplyr::summarise(hours = sum(hours))

tree_model_summer <- tree_model %>%
    dplyr::filter(season == "summer") %>%
    dplyr::group_by(condition) %>%
    dplyr::summarise(hours = sum(hours))

burr_model_summer <- burr_model %>%
    dplyr::filter(season == "summer") %>%
    dplyr::group_by(condition) %>%
    dplyr::summarise(hours = sum(hours))

tab_summer <- data.frame(strategy = c("Shade only", "Waterproof", "Burrowing"), curr_wet = c(shad_model_summer$hours[4],
    tree_model_summer$hours[4], burr_model_summer$hours[4]), curr_dry = c(shad_model_summer$hours[3],
    tree_model_summer$hours[3], burr_model_summer$hours[3]), warm_wet = c(shad_model_summer$hours[2],
    tree_model_summer$hours[2], burr_model_summer$hours[2]), warm_dry = c(shad_model_summer$hours[1],
    tree_model_summer$hours[1], burr_model_summer$hours[1])) %>%
    dplyr::mutate(delta_warm = (warm_wet - curr_wet)/curr_wet * 100, delta_dry = (curr_dry -
        curr_wet)/curr_wet * 100, delta_warm_dry = (warm_dry - curr_wet)/curr_wet *
        100) %>%
    dplyr::select(-c(curr_wet:warm_dry)) %>%
    tibble::add_row(strategy = "**Summer**", .before = 1)

# autumn
shad_model_autumn <- shad_model %>%
    dplyr::filter(season == "autumn") %>%
    dplyr::group_by(condition) %>%
    dplyr::summarise(hours = sum(hours))

tree_model_autumn <- tree_model %>%
    dplyr::filter(season == "autumn") %>%
    dplyr::group_by(condition) %>%
    dplyr::summarise(hours = sum(hours))

burr_model_autumn <- burr_model %>%
    dplyr::filter(season == "autumn") %>%
    dplyr::group_by(condition) %>%
    dplyr::summarise(hours = sum(hours))

tab_autumn <- data.frame(strategy = c("Shade only", "Waterproof", "Burrowing"), curr_wet = c(shad_model_autumn$hours[4],
    tree_model_autumn$hours[4], burr_model_autumn$hours[4]), curr_dry = c(shad_model_autumn$hours[3],
    tree_model_autumn$hours[3], burr_model_autumn$hours[3]), warm_wet = c(shad_model_autumn$hours[2],
    tree_model_autumn$hours[2], burr_model_autumn$hours[2]), warm_dry = c(shad_model_autumn$hours[1],
    tree_model_autumn$hours[1], burr_model_autumn$hours[1])) %>%
    dplyr::mutate(delta_warm = (warm_wet - curr_wet)/curr_wet * 100, delta_dry = (curr_dry -
        curr_wet)/curr_wet * 100, delta_warm_dry = (warm_dry - curr_wet)/curr_wet *
        100) %>%
    dplyr::select(-c(curr_wet:warm_dry)) %>%
    tibble::add_row(strategy = "**Autumn**", .before = 1)

# winter
shad_model_winter <- shad_model %>%
    dplyr::filter(season == "winter") %>%
    dplyr::group_by(condition) %>%
    dplyr::summarise(hours = sum(hours))

tree_model_winter <- tree_model %>%
    dplyr::filter(season == "winter") %>%
    dplyr::group_by(condition) %>%
    dplyr::summarise(hours = sum(hours))

burr_model_winter <- burr_model %>%
    dplyr::filter(season == "winter") %>%
    dplyr::group_by(condition) %>%
    dplyr::summarise(hours = sum(hours))

tab_winter <- data.frame(strategy = c("Shade only", "Waterproof", "Burrowing"), curr_wet = c(shad_model_winter$hours[4],
    tree_model_winter$hours[4], burr_model_winter$hours[4]), curr_dry = c(shad_model_winter$hours[3],
    tree_model_winter$hours[3], burr_model_winter$hours[3]), warm_wet = c(shad_model_winter$hours[2],
    tree_model_winter$hours[2], burr_model_winter$hours[2]), warm_dry = c(shad_model_winter$hours[1],
    tree_model_winter$hours[1], burr_model_winter$hours[1])) %>%
    dplyr::mutate(delta_warm = (warm_wet - curr_wet)/curr_wet * 100, delta_dry = (curr_dry -
        curr_wet)/curr_wet * 100, delta_warm_dry = (warm_dry - curr_wet)/curr_wet *
        100) %>%
    dplyr::select(-c(curr_wet:warm_dry)) %>%
    tibble::add_row(strategy = "**Winter**", .before = 1)

# spring
shad_model_spring <- shad_model %>%
    dplyr::filter(season == "spring") %>%
    dplyr::group_by(condition) %>%
    dplyr::summarise(hours = sum(hours))

tree_model_spring <- tree_model %>%
    dplyr::filter(season == "spring") %>%
    dplyr::group_by(condition) %>%
    dplyr::summarise(hours = sum(hours))

burr_model_spring <- burr_model %>%
    dplyr::filter(season == "spring") %>%
    dplyr::group_by(condition) %>%
    dplyr::summarise(hours = sum(hours))

tab_spring <- data.frame(strategy = c("Shade only", "Waterproof", "Burrowing"), curr_wet = c(shad_model_spring$hours[4],
    tree_model_spring$hours[4], burr_model_spring$hours[4]), curr_dry = c(shad_model_spring$hours[3],
    tree_model_spring$hours[3], burr_model_spring$hours[3]), warm_wet = c(shad_model_spring$hours[2],
    tree_model_spring$hours[2], burr_model_spring$hours[2]), warm_dry = c(shad_model_spring$hours[1],
    tree_model_spring$hours[1], burr_model_spring$hours[1])) %>%
    dplyr::mutate(delta_warm = (warm_wet - curr_wet)/curr_wet * 100, delta_dry = (curr_dry -
        curr_wet)/curr_wet * 100, delta_warm_dry = (warm_dry - curr_wet)/curr_wet *
        100) %>%
    dplyr::select(-c(curr_wet:warm_dry)) %>%
    tibble::add_row(strategy = "**Spring**", .before = 1)

# Render table
bind_rows(tab_summer, tab_autumn, tab_winter, tab_spring) %>%
    remove_rownames() %>%
    knitr::kable(col.names = c("Water-saving strategy", "$\\Delta$ warming only (%)",
        "$\\Delta$ drought only (%)", "$\\Delta$ warming and drought (%)"))
Water-saving strategy \(\Delta\) warming only (%) \(\Delta\) drought only (%) \(\Delta\) warming and drought (%)
Summer
Shade only -8.0 -11.0 -17.85
Waterproof -8.6 -9.5 -19.08
Burrowing -4.7 -4.5 -10.13
Autumn
Shade only 5.0 -1.7 3.55
Waterproof 2.2 -2.0 0.68
Burrowing 6.0 -1.1 5.26
Winter
Shade only 72.9 -2.3 65.68
Waterproof 42.8 -1.9 36.49
Burrowing 69.8 -2.6 66.47
Spring
Shade only 1.5 -2.2 -4.34
Waterproof -1.9 -2.9 -6.55
Burrowing 4.1 -1.2 1.66

Additional figures

temp_dat <- ewl_dat %>%
    dplyr::filter(!is.na(trt_temp))

temp_dat %>%
    ggplot(aes(x = trt_temp, y = skin_temp)) + geom_point(size = 2, colour = "grey") +
    geom_abline(intercept = 0, slope = 1, linetype = "dashed", size = 0.5) + stat_smooth(method = "lm",
    formula = y ~ x + I(x^4), se = F, colour = "black") + ylim(5, 50) + xlim(5, 50) +
    labs(x = "Air temperature (°C)", y = "Skin surface temperature (°C)") + mytheme()

Fig. S11. Relationship between exposed air temperature (°C) during the experiment and the observed skin surface temperature (°C) across 238 species. The black line represents the non-linear relationship between air temperature and skin temperature where the skin temperature remains at ~35°C when exposed to air temperatures > 40°C.

Figures

Code to produce the main document figures are detailed below. Figures produced were further modified in Adobe Illustrator for publication.

Figure 1 - AI risk

# Reproject maps
rob_proj <- "+proj=robin +lon_0=0 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m +no_defs"
world_rob <- spTransform(world_spdf, CRSobj = rob_proj)

# land
data("land", package = "tmap")
land_raster <- as(land, "Raster")  # convert from star to raster
land_df <- raster::as.data.frame(raster::rasterToPoints(land_raster))

elevation_raster <- projectRaster(land_raster$elevation, crs = rob_proj)
slope_raster <- raster::terrain(elevation_raster, opt = "slope")
aspect_raster <- raster::terrain(elevation_raster, opt = "aspect")
hill_raster <- hillShade(slope_raster, aspect_raster, 40, 270)  #setting the elevation angle (of the sun) to 40 and the direction angle of the light to 270
hill_m <- rasterToPoints(hill_raster)
hill_df <- data.frame(hill_m)
colnames(hill_df) <- c("lon", "lat", "hill")

# Fig 1a - AI current
AI_rob <- raster::projectRaster(ai_rast, crs = rob_proj)
AI_df_rob <- raster::as.data.frame(raster::rasterToPoints(AI_rob))
AI_df_rob <- AI_df_rob %>%
    # Recode
dplyr::mutate(category = case_when(is.infinite(layer) ~ "Humid", layer >= 0.65 ~
    "Humid", layer >= 0.5 & layer < 0.65 ~ "Dry sub-humid", layer >= 0.2 & layer <
    0.5 ~ "Semi-arid", layer >= 0.05 & layer < 0.2 ~ "Arid", layer < 0.05 ~ "Hyper-arid")) %>%
    # Convert to ordered factor
dplyr::mutate(category = factor(category, levels = c("Hyper-arid", "Arid", "Semi-arid",
    "Dry sub-humid", "Humid"), ordered = TRUE))

AI_2C_rob <- projectRaster(ai_2C_rast, crs = rob_proj)
AI_2C_df_rob <- raster::as.data.frame(raster::rasterToPoints(AI_2C_rob))
AI_2C_df_rob <- AI_2C_df_rob %>%
    # Recode
dplyr::mutate(category = case_when(is.infinite(layer) ~ "Humid", layer >= 0.65 ~
    "Humid", layer >= 0.5 & layer < 0.65 ~ "Dry sub-humid", layer >= 0.2 & layer <
    0.5 ~ "Semi-arid", layer >= 0.05 & layer < 0.2 ~ "Arid", layer < 0.05 ~ "Hyper-arid")) %>%
    # Convert to ordered factor
dplyr::mutate(category = factor(category, levels = c("Hyper-arid", "Arid", "Semi-arid",
    "Dry sub-humid", "Humid"), ordered = TRUE))

AI_4C_rob <- projectRaster(ai_4C_rast, crs = rob_proj)
AI_4C_df_rob <- raster::as.data.frame(raster::rasterToPoints(AI_4C_rob))
AI_4C_df_rob <- AI_4C_df_rob %>%
    # Recode
dplyr::mutate(category = case_when(is.infinite(layer) ~ "Humid", layer >= 0.65 ~
    "Humid", layer >= 0.5 & layer < 0.65 ~ "Dry sub-humid", layer >= 0.2 & layer <
    0.5 ~ "Semi-arid", layer >= 0.05 & layer < 0.2 ~ "Arid", layer < 0.05 ~ "Hyper-arid")) %>%
    # Convert to ordered factor
dplyr::mutate(category = factor(category, levels = c("Hyper-arid", "Arid", "Semi-arid",
    "Dry sub-humid", "Humid"), ordered = TRUE))

arid_col <- c("#8E063B", "#CB6D53", "#E99A2C", "#F5D579", "white")
aridity_plot <- ggplot() + geom_raster(data = AI_df_rob, aes(y = y, x = x, fill = category)) +
    geom_polygon(data = world_rob, aes(x = long, y = lat, group = group), colour = "#64686b",
        fill = NA, size = 0.1) + scale_fill_manual(values = arid_col, guide = guide_legend(reverse = TRUE)) +
    ggnewscale::new_scale("fill") + geom_raster(data = hill_df %>%
    filter(hill <= 0.645), aes(lon, lat, fill = hill, alpha = hill), show.legend = FALSE) +
    scale_fill_gradient(low = "black", high = "grey") + scale_alpha_continuous(trans = "reverse") +
    theme_void() + ylab(NULL) + xlab(NULL) + ggtitle("Aridity Index (1981-2010)") +
    scale_y_continuous(limits = c(-6100000, 8500000), expand = c(0, 0)) + scale_x_continuous(limits = c(-1.5e+07,
    1.6e+07), expand = c(0, 0)) + theme(axis.title = element_blank(), axis.text = element_blank(),
    axis.ticks = element_blank(), plot.title = element_text(size = 10)) + coord_fixed(ratio = 1)

# Fig 1b - Species richness
anuran_rob <- projectRaster(anuran_sr, crs = rob_proj)
anuran_df_rob <- raster::as.data.frame(raster::rasterToPoints(anuran_rob)) %>%
    dplyr::rename(species_n = layer)

sp_breaks = c(1, 5, 25, 100)
anuran_plot <- ggplot() + geom_raster(data = anuran_df_rob, aes(y = y, x = x, fill = species_n)) +
    geom_polygon(data = world_rob, aes(x = long, y = lat, group = group), colour = "#64686b",
        fill = NA, size = 0.1) + colorspace::scale_fill_continuous_sequential(palette = "BluGrn",
    trans = "log", breaks = sp_breaks, labels = sp_breaks) + ggnewscale::new_scale("fill") +
    geom_raster(data = hill_df %>%
        filter(hill <= 0.645), aes(lon, lat, fill = hill, alpha = hill), show.legend = FALSE) +
    scale_fill_gradient(low = "black", high = "grey") + scale_alpha_continuous(trans = "reverse") +
    theme_void() + ylab(NULL) + xlab(NULL) + ggtitle("Anuran species richness") +
    scale_y_continuous(limits = c(-6100000, 8500000), expand = c(0, 0)) + scale_x_continuous(limits = c(-1.5e+07,
    1.6e+07), expand = c(0, 0)) + theme(axis.title = element_blank(), axis.text = element_blank(),
    axis.ticks = element_blank(), plot.title = element_text(size = 10)) + coord_fixed()

AI_merged <- merge(AI_df_rob, AI_2C_df_rob, by = c("x", "y"), all.x = T) %>%
    merge(AI_4C_df_rob, by = c("x", "y"), all.x = T) %>%
    dplyr::rename(layer_current = layer.x, category_current = category.x, layer_2C = layer.y,
        category_2C = category.y, layer_4C = layer, category_4C = category) %>%
    dplyr::mutate(change_2C = (layer_2C - layer_current/layer_current) * 100, change_2C_AI = case_when(change_2C >=
        -2 & change_2C < 2 ~ "No change to wetter", change_2C >= -10 & change_2C <
        -2 ~ ">-2 to -10%", change_2C >= -20 & change_2C < -10 ~ ">-10 to -20%",
        change_2C >= -40 & change_2C < -20 ~ ">-20 to -40%", change_2C >= -80 & change_2C <
            -40 ~ ">-40 to -80%", change_2C < -80 ~ "<-80%"), change_4C = (layer_4C -
        layer_current/layer_current) * 100, change_4C_AI = case_when(change_4C >=
        -2 & change_4C < 2 ~ "No change to wetter", change_4C >= -10 & change_4C <
        -2 ~ ">-2 to -10%", change_4C >= -20 & change_4C < -10 ~ ">-10 to -20%",
        change_4C >= -40 & change_4C < -20 ~ ">-20 to -40%", change_4C >= -80 & change_4C <
            -40 ~ ">-40 to -80%", change_4C < -80 ~ "<-80%")) %>%
    filter(category_current != "Hyper-arid") %>%
    dplyr::mutate(change_2C_AI = factor(change_2C_AI, levels = c("<-80%", ">-40 to -80%",
        ">-20 to -40%", ">-10 to -20%", ">-2 to -10%", "No change to wetter"), ordered = TRUE),
        change_4C_AI = factor(change_4C_AI, levels = c("<-80%", ">-40 to -80%", ">-20 to -40%",
            ">-10 to -20%", ">-2 to -10%", "No change to wetter"), ordered = TRUE))

change_col <- c("#B13F63", "#D35D60", "#E38566", "#EEAC7D", "#F5D1A8", "white")

# Fig 1C - 2C Difference
change_2C_plot <- ggplot() + geom_raster(data = AI_merged, aes(y = y, x = x, fill = change_2C_AI)) +
    geom_polygon(data = world_rob, aes(x = long, y = lat, group = group), colour = "#64686b",
        fill = NA, size = 0.1) + scale_fill_manual(values = change_col, na.value = "white") +
    ggnewscale::new_scale("fill") + geom_raster(data = hill_df %>%
    filter(hill <= 0.645), aes(lon, lat, fill = hill, alpha = hill), show.legend = FALSE) +
    scale_fill_gradient(low = "black", high = "grey") + scale_alpha_continuous(trans = "reverse") +
    theme_void() + ylab(NULL) + xlab(NULL) + ggtitle(expression("Change in dryness (" *
    Delta * "AI +2°C)")) + scale_y_continuous(limits = c(-6100000, 8500000), expand = c(0,
    0)) + scale_x_continuous(limits = c(-1.5e+07, 1.6e+07), expand = c(0, 0)) + theme(axis.title = element_blank(),
    axis.text = element_blank(), axis.ticks = element_blank(), plot.title = element_text(size = 10)) +
    coord_fixed(ratio = 1)

# Fig 1d - 4C Difference
change_4C_plot <- ggplot() + geom_raster(data = AI_merged, aes(y = y, x = x, fill = change_4C_AI)) +
    geom_polygon(data = world_rob, aes(x = long, y = lat, group = group), colour = "#64686b",
        fill = NA, size = 0.1) + scale_fill_manual(values = change_col, na.value = "white") +
    ggnewscale::new_scale("fill") + geom_raster(data = hill_df %>%
    filter(hill <= 0.645), aes(lon, lat, fill = hill, alpha = hill), show.legend = FALSE) +
    scale_fill_gradient(low = "black", high = "grey") + scale_alpha_continuous(trans = "reverse") +
    theme_void() + ylab(NULL) + xlab(NULL) + ggtitle(expression("Change in dryness (" *
    Delta * "AI +4°C)")) + scale_y_continuous(limits = c(-6100000, 8500000), expand = c(0,
    0)) + scale_x_continuous(limits = c(-1.5e+07, 1.6e+07), expand = c(0, 0)) + theme(axis.title = element_blank(),
    axis.text = element_blank(), axis.ticks = element_blank(), plot.title = element_text(size = 10)) +
    coord_fixed(ratio = 1)

# Fig 1e - Dryness and species richness
arid_col_2 <- c("#8E063B", "#CB6D53", "#E99A2C", "#F5D579", "light grey")
species_ai_plot <- ai_sp_df %>%
    ggplot(aes(x = aridity, y = species_n, colour = category)) + geom_point(size = 2) +
    coord_trans(x = "sqrt") + scale_colour_manual(values = arid_col_2, guide = guide_legend(reverse = TRUE)) +
    scale_x_continuous(limits = c(0, 3), breaks = c(0, 0.05, 0.2, 0.5, 0.65)) + xlab("Precipitation / Evapotranspiration") +
    ylab("Species richness") + mytheme() + theme(legend.position = "none", axis.text.x = element_blank(),
    axis.ticks.x = element_blank())

# Fig 1f - Dryness and species richness by ecotype
ecotype_ai_plot <- ai_sp_df %>%
    dplyr::filter(aridity <= 3) %>%
    dplyr::select(aridity, species_n:stream_n) %>%
    tidyr::pivot_longer(!aridity, names_to = "ecotype", values_to = "mean") %>%
    dplyr::filter(ecotype != "species_n") %>%
    drop_na(mean) %>%
    dplyr::mutate(ecotype = factor(ecotype, levels = c("fossorial_n", "ground_n",
        "aquatic_n", "arboreal_n", "semi_aq_n", "stream_n"))) %>%
    ggplot(aes(x = aridity, y = ecotype, group = ecotype, fill = ecotype)) + ggridges::stat_density_ridges(scale = 1,
    rel_min_height = 0.01, alpha = 0.5, show.legend = FALSE) + scale_fill_viridis_d() +
    scale_x_continuous(trans = "sqrt") + labs(x = NULL, y = NULL) + mytheme()

# Fig 1g - Change in species AI Merge summary data by row
arid_sp_comb <- data.frame(bind_rows(ai_sp_sum, ai_2C_sp_sum, ai_4C_sp_sum))
arid_sp_comb$scenario <- forcats::fct_relevel(arid_sp_comb$scenario, "Current")

species_occ_plot <- arid_sp_comb %>%
    ggplot(aes(x = category, y = log(all_freq), group = scenario, colour = scenario,
        shape = scenario)) + geom_point(position = position_dodge(width = 0.5), size = 1.5) +
    scale_colour_manual(values = c("#F5D579", "#CB6D53", "#8E063B")) + scale_y_continuous(breaks = pretty(log(arid_sp_comb$all_freq)),
    labels = pretty(arid_sp_comb$all_freq)) + ylab("% species") + xlab(NULL) + mytheme() +
    theme(legend.position = "none")

# Fig 1
plot_grid(species_ai_plot, ecotype_ai_plot, species_occ_plot, align = "v", ncol = 3)  # plot in between.
cowplot::plot_grid(aridity_plot + theme(legend.position = "bottom"), anuran_plot +
    theme(legend.position = "bottom"), change_2C_plot + theme(legend.position = "bottom"),
    change_4C_plot + theme(legend.position = "bottom"), align = "h", axis = "bt",
    ncol = 2)

Figure 2 - PDSI risk

PDSI_risk_rob <- raster::projectRaster(raster::stack(PDSI_2C_diff_rast, PDSI_4C_diff_rast, PDSI_freq_diff, PDSI_dur_diff,
                                                     resample(anuran_sr, PDSI_4C_diff_rast)), 
                                       crs = rob_proj)
                             
PDSI_risk_df <- raster::as.data.frame(raster::rasterToPoints(PDSI_risk_rob)) %>%
  dplyr::rename("sp_n" = layer) %>%
  dplyr::filter(!is.na(sp_n)) %>%
  dplyr::mutate(delta_int_2C_bin = ifelse(delta_int_2C < -1, 1, 0), # delta_PDSI < -1
         delta_int_4C_bin = ifelse(delta_int_4C < -1, 1, 0), # delta_PDSI < -1
         delta_freq_2C_bin = ifelse(delta_freq_2C >1, 1, 0), # month > 1
         delta_freq_4C_bin = ifelse(delta_freq_4C >1, 1, 0), # month > 1
         delta_dur_2C_bin = ifelse(delta_dur_2C >1, 1, 0), # month > 1
         delta_dur_4C_bin = ifelse(delta_dur_4C >1, 1, 0)) %>% # month > 1 
  dplyr::rowwise() %>%
  dplyr::mutate(count_2C = sum(delta_int_2C_bin, delta_freq_2C_bin, delta_dur_2C_bin, na.rm = T),
         
         count_4C = sum(delta_int_4C_bin, delta_freq_4C_bin, delta_dur_4C_bin, na.rm = T),
         risk_2C  = sp_n * count_2C,
         risk_4C  = sp_n * count_4C,
         count_2C = factor(count_2C, levels = c("3", "2", "1")),
         count_4C = factor(count_4C, levels = c("3", "2", "1"))
         ) %>%
  data.frame()

# Plot
PDSI_risk_2C_plot <- ggplot() +
  geom_raster(data = PDSI_risk_df, aes(y = y, x = x, fill = count_2C)) +
  geom_polygon(data = world_rob, aes(x = long, y = lat, group = group), colour = "#64686b", fill = NA, size = 0.1) +
  scale_fill_discrete_sequential(palette = "RedOr", rev = F) +
  ggnewscale::new_scale("fill") +
  geom_raster(data = hill_df %>% filter(hill <= 0.645), aes(lon, lat, fill = hill, alpha = hill), show.legend = FALSE) +
  scale_fill_gradient(low = "black", high = "grey") +
  scale_alpha_continuous(trans = "reverse") +
  theme_void() + ylab(NULL) + xlab(NULL) +
  ggtitle(expression("+2°C by 2080-2100")) +
  scale_y_continuous(limits = c(-61e5, 85e5), expand = c(0, 0)) +
  scale_x_continuous(limits = c(-15e6, 16e6), expand = c(0, 0)) +
  theme(axis.title = element_blank(),
        axis.text = element_blank(),
        axis.ticks = element_blank(),
        plot.title = element_text(size = 10)) +
  coord_fixed(ratio = 1) # fixed ratio

PDSI_risk_4C_plot <- ggplot() +
  geom_raster(data = PDSI_risk_df, aes(y = y, x = x, fill = count_4C)) +
  geom_polygon(data = world_rob, aes(x = long, y = lat, group = group), colour = "#64686b", fill = NA, size = 0.1) +
  scale_fill_discrete_sequential(palette = "RedOr", rev = F) +
  ggnewscale::new_scale("fill") +
  geom_raster(data = hill_df %>% filter(hill <= 0.645), aes(lon, lat, fill = hill, alpha = hill), show.legend = FALSE) +
  scale_fill_gradient(low = "black", high = "grey") +
  scale_alpha_continuous(trans = "reverse") +
  theme_void() + ylab(NULL) + xlab(NULL) +
  ggtitle(expression("+4°C by 2080-2100")) +
  scale_y_continuous(limits = c(-61e5, 85e5), expand = c(0, 0)) +
  scale_x_continuous(limits = c(-15e6, 16e6), expand = c(0, 0)) +
  theme(axis.title = element_blank(),
        axis.text = element_blank(),
        axis.ticks = element_blank(),
        plot.title = element_text(size = 10)) +
  coord_fixed(ratio = 1) # fixed ratio

sp_2C_plot <- PDSI_risk_df %>%
  dplyr::mutate(risk_2C_cat = case_when(
    risk_2C == 0 ~ '0',
    risk_2C > 0 & risk_2C <=1 ~ '<1',
    risk_2C > 1 & risk_2C < 5 ~ '>1 to 5',
    risk_2C >= 5 & risk_2C < 10 ~ '>5 to 10',
    risk_2C >= 10 & risk_2C < 20 ~ '>10 to 20',
    risk_2C >= 20 & risk_2C < 100 ~ '>20 to 100',
    risk_2C >= 100 & risk_2C < 200 ~ '>100 to 200',
    risk_2C > 200 ~ '>200'),
    risk_2C = na_if(risk_2C, 0),
    risk_2C_cat = factor(risk_2C_cat,
                                   levels = c('>200','>100 to 200', '>20 to 100','>10 to 20', '>5 to 10', '>1 to 5', '<1'))) %>%
  ggplot() +
  geom_raster(aes(y = y, x = x, fill = risk_2C_cat)) +
  geom_polygon(data = world_rob, aes(x = long, y = lat, group = group), colour = "#64686b", fill = NA, size = 0.1) +
  scale_fill_discrete_sequential(palette = "Heat", rev = F) +
  ggnewscale::new_scale("fill") +
  geom_raster(data = hill_df %>% filter(hill <= 0.645), aes(lon, lat, fill = hill, alpha = hill), show.legend = FALSE) +
  scale_fill_gradient(low = "black", high = "grey") +
  scale_alpha_continuous(trans = "reverse") +
  theme_void() + ylab(NULL) + xlab(NULL) +
  scale_y_continuous(limits = c(-61e5, 85e5), expand = c(0, 0)) +
  scale_x_continuous(limits = c(-15e6, 16e6), expand = c(0, 0)) +
  theme(axis.title = element_blank(),
        axis.text = element_blank(),
        axis.ticks = element_blank(),
        plot.title = element_text(size = 10)) +
  coord_fixed(ratio = 1) # fixed ratio

sp_4C_plot <- PDSI_risk_df %>%
  dplyr::mutate(risk_4C_cat = case_when(
    risk_4C == 0 ~ '0',
    risk_4C > 0 & risk_4C <=1 ~ '<1',
    risk_4C > 1 & risk_4C < 5 ~ '>1 to 5',
    risk_4C >= 5 & risk_4C < 10 ~ '>5 to 10',
    risk_4C >= 10 & risk_4C < 20 ~ '>10 to 20',
    risk_4C >= 20 & risk_4C < 100 ~ '>20 to 100',
    risk_4C >= 100 & risk_4C < 200 ~ '>100 to 200',
    risk_4C > 200 ~ '>200'),
    risk_4C = na_if(risk_4C, 0),
    risk_4C_cat = factor(risk_4C_cat,
                                   levels = c('>200','>100 to 200', '>20 to 100','>10 to 20', '>5 to 10', '>1 to 5', '<1'))) %>%
  ggplot() +
  geom_raster(aes(y = y, x = x, fill = risk_4C_cat)) +
  geom_polygon(data = world_rob, aes(x = long, y = lat, group = group), colour = "#64686b", fill = NA, size = 0.1) +
  scale_fill_discrete_sequential(palette = "Heat", rev = F) +
  ggnewscale::new_scale("fill") +
  geom_raster(data = hill_df %>% filter(hill <= 0.645), aes(lon, lat, fill = hill, alpha = hill), show.legend = FALSE) +
  scale_fill_gradient(low = "black", high = "grey") +
  scale_alpha_continuous(trans = "reverse") +
  theme_void() + ylab(NULL) + xlab(NULL) +
  scale_y_continuous(limits = c(-61e5, 85e5), expand = c(0, 0)) +
  scale_x_continuous(limits = c(-15e6, 16e6), expand = c(0, 0)) +
  theme(axis.title = element_blank(),
        axis.text = element_blank(),
        axis.ticks = element_blank(),
        plot.title = element_text(size = 10)) +
  coord_fixed(ratio = 1) # fixed ratio

cowplot::plot_grid(PDSI_risk_2C_plot + theme(legend.position = "none"),
                   PDSI_risk_4C_plot + theme(legend.position = "none"),
                   sp_2C_plot + theme(legend.position = "none"),
                   sp_4C_plot + theme(legend.position = "none"),
                   ncol = 2,
                   align = "h", axis = "bt", labels = c('a', 'b', 'c', 'd'))
#PDSI_risk_df %>%
  #group_by(count_2C) %>%
  #summarise(length = length(count_2C)) %>%
  #mutate(freq = length / length(PDSI_risk_df$count_2C) * 100)

#PDSI_risk_df %>%
  #group_by(count_4C) %>%
  #summarise(length = length(count_4C)) %>%
  #mutate(freq = length / length(PDSI_risk_df$count_4C) * 100)

Figure 3 - Water loss

# Fig. 3a - EWL
lnVPD_conditions <- list(lnVPD = setNames(c(-4.60517, -2.302585, 0, 2.302585), 
                                        c(round(exp(-4.60517), digits = 2), 
                                          round(exp(-2.302585), digits = 1), 
                                          exp(0), 
                                          round(exp(2.302585), digits = 1))))

ewl_ce <- conditional_effects(ewl_model, effects = "lnMass:lnVPD", int_conditions = lnVPD_conditions)

ewl_ce <- data.frame(ewl_ce[[1]]) %>%
  dplyr::rename(estimate = estimate__,
                VPD_cal  = effect2__) %>%
  dplyr::mutate(mean_mass_g = exp(lnMass),
         VPD_kPa     = exp(lnVPD),
         VPD_cal     = as.numeric(as.character(VPD_cal)))

ewl_mass_plot <- ewl_dat %>%
  ggplot() +
  geom_point(aes(x = mean_mass_g, y = mg_h_mean, shape = strategy), size = 2, colour = "grey") +
  geom_line(data = ewl_ce, aes(x = mean_mass_g, y = exp(estimate), group = lnVPD, colour = lnVPD), size = 1) +
  geom_text(data = ewl_ce %>% filter(mean_mass_g == last(mean_mass_g)), 
            aes(label = VPD_cal, x = mean_mass_g + 50, y = exp(estimate), hjust = -0.01),
            size = 3) +
  labs(x = "Body mass (g)", colour = "VPD (kPa)", shape = NULL) +
  ylab(expression("EWL"~("mg"~H[2]*O~h^{"-1"}))) +
  scale_y_continuous(trans = scales::log_trans(), breaks = c(0.1, 1, 10, 100, 1000), labels = c(0.1, 1, 10, 100, "1,000")) +
  scale_x_continuous(trans = 'log10') +
  expand_limits(x = 500) +
  scale_colour_gradient2(low = "#255668", mid = "#17A77E", high = "#82CC6C", 
                         midpoint = -1,
                         breaks = c(-4.60517, -2.302585, 0, 2.302585), 
                         labels = c(round(exp(-4.60517), digits = 2), 
                                     round(exp(-2.302585), digits = 1), 
                                     exp(0), 
                                     round(exp(2.302585), digits = 1))) +
  scale_shape_manual(values = c(16, 1, 2, 0)) +
  mytheme() + theme(legend.position = "right") +
  guides(colour = guide_colourbar(barheight = 5, barwidth = 0.5, label.position = "right"))

# Fig. 3b
# VPD
VPD_rast <- raster::projectRaster(raster::stack(x = file.path(spatial_path, 'TerraClimate19812010_vpd.nc')), anuran_sr) # VPD year 1981-2010 (kPa)
VPD_mean_rast <- raster::calc(VPD_rast, fun = mean, na.rm = TRUE) 
names(VPD_mean_rast) <-"VPD"

# Wind speed
ws_rast <- raster::projectRaster(raster::stack(x = file.path(spatial_path, 'TerraClimate19812010_ws.nc')), anuran_sr) # Wind speed year 1981-2010 (m/s)
ws_mean_rast <- raster::calc(ws_rast, fun = mean, na.rm = TRUE) 
names(ws_mean_rast) <-"wind_speed"

EWL_risk_rob <- raster::projectRaster(raster::stack(VPD_mean_rast, ws_mean_rast,
                                                    resample(anuran_sr, VPD_mean_rast)), 
                                       crs = rob_proj)

# Estimate EWL for a 30 g ground-dwelling frog
VPD_sp_df <- raster::as.data.frame(raster::rasterToPoints(EWL_risk_rob)) %>% 
  rename(species_n = layer) %>%
  drop_na(species_n) %>%
  dplyr::mutate(wind_speed_cm_s = wind_speed * 100, # from m/s to cm/s
                u = 0.4 * wind_speed_cm_s / log((100 / 0.15) + 1), # u = friction velocity
                wind_speed_corr = 2.5 * u * log((1 / 0.15) + 1), # correct for reference height (10 m) to ground level (1 cm) assuming level ground
                EWL_pred = 3.74 - 0.11 + (log(Ww_g) * 0.55) + (log(VPD) * 0.28) + (log(wind_speed_corr) * 0.34),
                EWL_pred = exp(EWL_pred) * 0.001 # from mg/h to g/h
                )

VPD_sp_plot <- VPD_sp_df %>%
  ggplot() +
  geom_raster(aes(y = y, x = x, fill = EWL_pred)) +
  geom_polygon(data = world_rob, aes(x = long, y = lat, group = group), colour = "#64686b", fill = NA, size = 0.1) +
  scale_fill_continuous_sequential(palette = "YlGnBu", rev = T, 
                                   name = expression("EWL"~("g"~H[2]*O~h^{"-1"}))) +
  ggnewscale::new_scale("fill") +
  geom_raster(data = hill_df %>% filter(hill <= 0.645), aes(lon, lat, fill = hill, alpha = hill), show.legend = FALSE) +
  scale_fill_gradient(low = "black", high = "grey") +
  scale_alpha_continuous(trans = "reverse") +
  theme_void() + ylab(NULL) + xlab(NULL) +
  scale_y_continuous(limits = c(-61e5, 85e5), expand = c(0, 0)) +
  scale_x_continuous(limits = c(-15e6, 16e6), expand = c(0, 0)) +
  guides(fill = guide_colourbar(barwidth = 20, barheight = 0.2, 
                                label.position = "bottom")) +
  theme_void() + ylab(NULL) + xlab(NULL) +
  theme(axis.title = element_blank(),
        axis.text = element_blank(),
        axis.ticks = element_blank(),
        plot.title = element_text(size = 10),
        legend.title = element_text(size = 8), 
        legend.position = "bottom") +
  coord_fixed(ratio = 1) # fixed ratio

cowplot::plot_grid(ewl_mass_plot,
                   VPD_sp_plot,
                   ncol = 1,
                   align = "h", axis = "bt", labels = c('a', 'b'), rel_heights = c(0.8, 1))

Figure 4 - Activity risk

shad_plot <- shad_model %>%
    ggplot(aes(x = day, y = condition, fill = hours)) + geom_tile() + scale_fill_continuous_diverging(palette = "Blue-Red 3",
    mid = 12, rev = TRUE) + ylab(NULL) + xlab("Day of the year") + scale_x_continuous(expand = c(0,
    0)) + mytheme() + theme(legend.position = "bottom") + guides(fill = guide_colourbar(barheight = 0.5,
    barwidth = 5, label.position = "bottom"))

tree_plot <- tree_model %>%
    ggplot(aes(x = day, y = condition, fill = hours)) + geom_tile() + scale_fill_continuous_diverging(palette = "Blue-Red 3",
    mid = 12, rev = TRUE) + ylab(NULL) + xlab("Day of the year") + scale_x_continuous(expand = c(0,
    0)) + mytheme() + theme(legend.position = "bottom") + guides(fill = guide_colourbar(barheight = 0.5,
    barwidth = 5, label.position = "bottom"))

burr_plot <- burr_model %>%
    ggplot(aes(x = day, y = condition, fill = hours)) + geom_tile() + scale_fill_continuous_diverging(palette = "Blue-Red 3",
    mid = 12, rev = TRUE) + ylab(NULL) + xlab("Day of the year") + scale_x_continuous(expand = c(0,
    0)) + mytheme() + theme(legend.position = "bottom") + guides(fill = guide_colourbar(barheight = 0.5,
    barwidth = 5, label.position = "bottom"))

prow_2 <- cowplot::plot_grid(shad_plot + theme(legend.position = "none"), tree_plot +
    theme(legend.position = "none"), burr_plot + theme(legend.position = "none"),
    ncol = 1, labels = c("a", "b", "c"), align = "v", axis = "l")

legend_b_2 <- cowplot::get_legend(burr_plot + guides(color = guide_legend(nrow = 1)))

plot_grid(prow_2, legend_b_2, nrow = 1, rel_heights = c(1, 0.1))

Extended data

Extended Figure 1 - PDSI intensity risk

PDSI_2C_diff_rast_crop <- raster::mask(crop(PDSI_2C_diff_rast, extent(world)), world)  # crop 
PDSI_2C_rob <- raster::projectRaster(raster::stack(PDSI_2C_diff_rast_crop, resample(anuran_sr,
    PDSI_2C_diff_rast_crop)), crs = rob_proj)

PDSI_4C_diff_rast_crop <- raster::mask(crop(PDSI_4C_diff_rast, extent(world)), world)  # crop 
PDSI_4C_rob <- raster::projectRaster(raster::stack(PDSI_4C_diff_rast_crop, resample(anuran_sr,
    PDSI_4C_diff_rast_crop)), crs = rob_proj)

PDSI_2C_df_rob <- raster::as.data.frame(raster::rasterToPoints(PDSI_2C_rob)) %>%
    dplyr::rename(layer = delta_int_2C, species_n = layer) %>%
    dplyr::mutate(change = case_when(layer >= 4 ~ "4", layer >= 3 & layer < 4 ~ "3",
        layer >= 2 & layer < 3 ~ "2", layer >= 1 & layer < 2 ~ "1", layer >= -1 &
            layer < 1 ~ "0", layer >= -2 & layer < -1 ~ "-1", layer >= -3 & layer <
            -2 ~ "-2", layer >= -4 & layer < -3 ~ "-3", layer < -4 ~ "-4")) %>%
    dplyr::mutate(change = factor(change, levels = c("-4", "-3", "-2", "-1", "0",
        "1", "2", "3", "4"), ordered = TRUE)) %>%
    dplyr::filter(change != "NA" & species_n != "NA")

PDSI_4C_df_rob <- raster::as.data.frame(raster::rasterToPoints(PDSI_4C_rob)) %>%
    dplyr::rename(layer = delta_int_4C, species_n = layer) %>%
    dplyr::mutate(change = case_when(layer >= 4 ~ "4", layer >= 3 & layer < 4 ~ "3",
        layer >= 2 & layer < 3 ~ "2", layer >= 1 & layer < 2 ~ "1", layer >= -1 &
            layer < 1 ~ "0", layer >= -2 & layer < -1 ~ "-1", layer >= -3 & layer <
            -2 ~ "-2", layer >= -4 & layer < -3 ~ "-3", layer < -4 ~ "-4")) %>%
    dplyr::mutate(change = factor(change, levels = c("-4", "-3", "-2", "-1", "0",
        "1", "2", "3", "4"), ordered = TRUE)) %>%
    dplyr::filter(change != "NA" & species_n != "NA")

# Intensity +2C - Ex Fig. 1a
colours_PDSI <- RColorBrewer::brewer.pal(9, "RdBu")
PDSI_2C_plot <- ggplot() + geom_raster(data = PDSI_2C_df_rob, aes(y = y, x = x, fill = change)) +
    geom_polygon(data = world_rob, aes(x = long, y = lat, group = group), colour = "#64686b",
        fill = NA, size = 0.1) + scale_fill_manual(values = colours_PDSI) + ggnewscale::new_scale("fill") +
    geom_raster(data = hill_df %>%
        filter(hill <= 0.645), aes(lon, lat, fill = hill, alpha = hill), show.legend = FALSE) +
    scale_fill_gradient(low = "black", high = "grey") + scale_alpha_continuous(trans = "reverse") +
    theme_void() + ylab(NULL) + xlab(NULL) + ggtitle(expression(Delta * "PDSI intensity (+2°C)")) +
    scale_y_continuous(limits = c(-6100000, 8500000), expand = c(0, 0)) + scale_x_continuous(limits = c(-1.5e+07,
    1.6e+07), expand = c(0, 0)) + theme(axis.title = element_blank(), axis.text = element_blank(),
    axis.ticks = element_blank(), plot.title = element_text(size = 10)) + coord_fixed(ratio = 1)  # fixed ratio

# Intensity +4C - Ex Fig. 1c
PDSI_4C_plot <- ggplot() + geom_raster(data = PDSI_4C_df_rob, aes(y = y, x = x, fill = change)) +
    geom_polygon(data = world_rob, aes(x = long, y = lat, group = group), colour = "#64686b",
        fill = NA, size = 0.1) + scale_fill_manual(values = colours_PDSI) + ggnewscale::new_scale("fill") +
    geom_raster(data = hill_df %>%
        filter(hill <= 0.645), aes(lon, lat, fill = hill, alpha = hill), show.legend = FALSE) +
    scale_fill_gradient(low = "black", high = "grey") + scale_alpha_continuous(trans = "reverse") +
    theme_void() + ylab(NULL) + xlab(NULL) + ggtitle(expression(Delta * "PDSI intensity (+4°C)")) +
    scale_y_continuous(limits = c(-6100000, 8500000), expand = c(0, 0)) + scale_x_continuous(limits = c(-1.5e+07,
    1.6e+07), expand = c(0, 0)) + theme(axis.title = element_blank(), axis.text = element_blank(),
    axis.ticks = element_blank(), plot.title = element_text(size = 10)) + coord_fixed(ratio = 1)  # fixed ratio

# 2C change - Ex Fig 1b
PDSI_sp_2C_plot <- PDSI_sp_2C %>%
    rows_insert(tibble(change_2C = "4", all_freq = 0), conflict = "ignore") %>%
    filter(change_2C != "NA") %>%
    ggplot(aes(x = change_2C, y = all_freq, fill = change_2C)) + geom_bar(stat = "identity") +
    scale_fill_manual(values = colours_PDSI) + geom_text(aes(label = round(all_freq,
    1)), vjust = -1, size = 2) + ylab("% species") + xlab("PDSI") + ylim(0, 80) +
    ggtitle("Grid cell occupied +2°C") + mytheme() + theme(plot.title = element_text(size = 10))

# 4C change - Ex Fig 1d
PDSI_sp_4C_plot <- PDSI_sp_4C %>%
    filter(change_4C != "NA") %>%
    ggplot(aes(x = change_4C, y = all_freq, fill = change_4C)) + geom_bar(stat = "identity") +
    scale_fill_manual(values = colours_PDSI) + geom_text(aes(label = round(all_freq,
    1)), vjust = -1, size = 2) + ylab("% species") + xlab("PDSI") + ylim(0, 80) +
    ggtitle("Grid cell occupied +4°C") + mytheme() + theme(plot.title = element_text(size = 10))

left_plot <- cowplot::plot_grid(PDSI_2C_plot + theme(legend.position = "none"), PDSI_4C_plot +
    theme(legend.position = "none"), ncol = 1, align = "h", axis = "bt", labels = c("a",
    "c", "e"))

right_plot <- cowplot::plot_grid(PDSI_sp_2C_plot + theme(legend.position = "none"),
    PDSI_sp_4C_plot + theme(legend.position = "none"), ncol = 1, align = "h", axis = "bt",
    labels = c("b", "d", "f"))

cowplot::plot_grid(left_plot, right_plot, ncol = 2, rel_widths = c(1, 0.7))

Extended Figure 2 - PDSI frequency risk

freq_diff_rast_crop <- raster::mask(crop(freq_diff_rast, extent(world)), world)  # crop

PDSI_freq_rob <- raster::projectRaster(raster::stack(freq_diff_rast_crop, resample(anuran_sr,
    freq_diff_rast_crop)), crs = rob_proj)

PDSI_freq_2C_df <- raster::as.data.frame(raster::rasterToPoints(PDSI_freq_rob)) %>%
    dplyr::mutate(diff_2C_cat = case_when(diff_2C >= 10 ~ "10-12", diff_2C >= 8 &
        diff_2C < 10 ~ "8-10", diff_2C >= 6 & diff_2C < 8 ~ "6-8", diff_2C >= 4 &
        diff_2C < 6 ~ "4-6", diff_2C >= 2 & diff_2C < 4 ~ "2-4", diff_2C >= 1 & diff_2C <
        2 ~ "1-2", diff_2C > 0 & diff_2C < 1 ~ "0-1", diff_2C >= -1 & diff_2C < 0 ~
        "-0-1", diff_2C >= -2 & diff_2C < -1 ~ "-1-2", diff_2C >= -4 & diff_2C <
        -2 ~ "-2-4")) %>%
    dplyr::mutate(diff_2C_cat = factor(diff_2C_cat, levels = c("10-12", "8-10", "6-8",
        "4-6", "2-4", "1-2", "0-1", "-0-1", "-1-2", "-2-4"), ordered = TRUE)) %>%
    dplyr::filter(diff_2C_cat != "NA" & layer != "NA")

PDSI_freq_4C_df <- raster::as.data.frame(raster::rasterToPoints(PDSI_freq_rob)) %>%
    dplyr::mutate(diff_4C_cat = case_when(diff_4C >= 10 ~ "10-12", diff_4C >= 8 &
        diff_4C < 10 ~ "8-10", diff_4C >= 6 & diff_4C < 8 ~ "6-8", diff_4C >= 4 &
        diff_4C < 6 ~ "4-6", diff_4C >= 2 & diff_4C < 4 ~ "2-4", diff_4C >= 1 & diff_4C <
        2 ~ "1-2", diff_4C > 0 & diff_4C < 1 ~ "0-1", diff_4C >= -1 & diff_4C < 0 ~
        "-0-1", diff_4C >= -2 & diff_4C < -1 ~ "-1-2", diff_4C >= -4 & diff_4C <
        -2 ~ "-2-4")) %>%
    dplyr::mutate(diff_4C_cat = factor(diff_4C_cat, levels = c("10-12", "8-10", "6-8",
        "4-6", "2-4", "1-2", "0-1", "-0-1", "-1-2", "-2-4"), ordered = TRUE)) %>%
    dplyr::filter(diff_4C_cat != "NA" & layer != "NA")

# Freq map 2C - Fig S10a
freq_2C_plot <- ggplot() + geom_raster(data = PDSI_freq_2C_df, aes(y = y, x = x,
    fill = diff_2C_cat)) + geom_polygon(data = world_rob, aes(x = long, y = lat,
    group = group), colour = "#64686b", fill = NA, size = 0.1) + scale_fill_manual(values = c("#67001F",
    "#B2182B", "#D6604D", "#F4A582", "#FDDBC7", "#FAE9DF", "#F7F7F7", "#dfebf2")) +
    ggnewscale::new_scale("fill") + geom_raster(data = hill_df %>%
    filter(hill <= 0.645), aes(lon, lat, fill = hill, alpha = hill), show.legend = FALSE) +
    scale_fill_gradient(low = "black", high = "grey") + scale_alpha_continuous(trans = "reverse") +
    theme_void() + ylab(NULL) + xlab(NULL) + ggtitle(expression("Change in drought frequency (" *
    Delta * "PDSI +2°C)")) + scale_y_continuous(limits = c(-6100000, 8500000), expand = c(0,
    0)) + scale_x_continuous(limits = c(-1.5e+07, 1.6e+07), expand = c(0, 0)) + theme(axis.title = element_blank(),
    axis.text = element_blank(), axis.ticks = element_blank(), plot.title = element_text(size = 10)) +
    coord_fixed(ratio = 1)  # fixed ratio

# Freq map 4C - Fig S10c
freq_4C_plot <- ggplot() + geom_raster(data = PDSI_freq_4C_df, aes(y = y, x = x,
    fill = diff_4C_cat)) + geom_polygon(data = world_rob, aes(x = long, y = lat,
    group = group), colour = "#64686b", fill = NA, size = 0.1) + scale_fill_manual(values = c("#67001F",
    "#B2182B", "#D6604D", "#F4A582", "#FDDBC7", "#FAE9DF", "#F7F7F7", "#dfebf2")) +
    ggnewscale::new_scale("fill") + geom_raster(data = hill_df %>%
    filter(hill <= 0.645), aes(lon, lat, fill = hill, alpha = hill), show.legend = FALSE) +
    scale_fill_gradient(low = "black", high = "grey") + scale_alpha_continuous(trans = "reverse") +
    theme_void() + ylab(NULL) + xlab(NULL) + ggtitle(expression("Change in drought frequency (" *
    Delta * "PDSI +4°C)")) + scale_y_continuous(limits = c(-6100000, 8500000), expand = c(0,
    0)) + scale_x_continuous(limits = c(-1.5e+07, 1.6e+07), expand = c(0, 0)) + theme(axis.title = element_blank(),
    axis.text = element_blank(), axis.ticks = element_blank(), plot.title = element_text(size = 10)) +
    coord_fixed(ratio = 1)  # fixed ratio

# 2C change - Fig S10b
freq_sp_2C <- data.frame(PDSI_freq_2C_df %>%
    dplyr::group_by(diff_2C_cat) %>%
    dplyr::summarise(species_n = length(layer[!is.na(layer)]))) %>%
    dplyr::mutate(all_freq = species_n/sum(species_n) * 100)

freq_sp_2C_plot <- freq_sp_2C %>%
    ggplot(aes(x = diff_2C_cat, y = all_freq, fill = diff_2C_cat)) + geom_bar(stat = "identity") +
    scale_fill_manual(values = c("#67001F", "#B2182B", "#D6604D", "#F4A582", "#FDDBC7",
        "#FAE9DF", "#F7F7F7", "#dfebf2")) + geom_text(aes(label = round(all_freq,
    1)), vjust = -1, size = 2) + ylab("% species") + xlab("Months") + ylim(0, 60) +
    ggtitle("Grid cell occupied +2°C") + mytheme() + theme(plot.title = element_text(size = 10))

# 4C change - Fig S10d
freq_sp_4C <- data.frame(PDSI_freq_4C_df %>%
    dplyr::group_by(diff_4C_cat) %>%
    dplyr::summarise(species_n = length(layer[!is.na(layer)]))) %>%
    dplyr::mutate(all_freq = species_n/sum(species_n) * 100)

freq_sp_4C_plot <- freq_sp_4C %>%
    ggplot(aes(x = diff_4C_cat, y = all_freq, fill = diff_4C_cat)) + geom_bar(stat = "identity") +
    scale_fill_manual(values = c("#67001F", "#B2182B", "#D6604D", "#F4A582", "#FDDBC7",
        "#FAE9DF", "#F7F7F7", "#dfebf2")) + geom_text(aes(label = round(all_freq,
    1)), vjust = -1, size = 2) + ylab("% species") + xlab("Months") + ylim(0, 60) +
    ggtitle("Grid cell occupied +4°C") + mytheme() + theme(plot.title = element_text(size = 10))

left_plot2 <- cowplot::plot_grid(freq_2C_plot + theme(legend.position = "none"),
    freq_4C_plot + theme(legend.position = "none"), ncol = 1, align = "h", axis = "bt",
    labels = c("a", "c"))

right_plot2 <- cowplot::plot_grid(freq_sp_2C_plot + theme(legend.position = "none"),
    freq_sp_4C_plot + theme(legend.position = "none"), ncol = 1, align = "h", axis = "bt",
    labels = c("b", "d"))

cowplot::plot_grid(left_plot2, right_plot2, ncol = 2, rel_widths = c(1, 0.7))

Extended Figure 3 - PDSI duration risk

PDSI_dur_diff_crop <- raster::mask(crop(PDSI_dur_diff, extent(world)), world)  # crop

PDSI_dur_rob <- raster::projectRaster(raster::stack(PDSI_dur_diff_crop, resample(anuran_sr,
    PDSI_dur_diff_crop)), crs = rob_proj)

PDSI_dur_2C_df <- raster::as.data.frame(raster::rasterToPoints(PDSI_dur_rob)) %>%
    dplyr::rename(sp_n = layer) %>%
    dplyr::filter(!is.na(sp_n)) %>%
    dplyr::mutate(diff_2C_cat = case_when(delta_dur_2C >= 10 ~ ">10", delta_dur_2C >=
        8 & delta_dur_2C < 10 ~ "8-10", delta_dur_2C >= 6 & delta_dur_2C < 8 ~ "6-8",
        delta_dur_2C >= 4 & delta_dur_2C < 6 ~ "4-6", delta_dur_2C >= 2 & delta_dur_2C <
            4 ~ "2-4", delta_dur_2C >= 1 & delta_dur_2C < 2 ~ "1-2", delta_dur_2C >
            0 & delta_dur_2C < 1 ~ "0-1", delta_dur_2C >= -1 & delta_dur_2C < 0 ~
            "-0-1", delta_dur_2C >= -2 & delta_dur_2C < -1 ~ "-1-2", delta_dur_2C >=
            -4 & delta_dur_2C < -2 ~ "-2-4", delta_dur_2C >= -8 & delta_dur_2C <
            -6 ~ "-6-8", delta_dur_2C >= -10 & delta_dur_2C < -8 ~ "-8-10", delta_dur_2C <
            -10 ~ "<-10")) %>%
    dplyr::mutate(diff_2C_cat = factor(diff_2C_cat, levels = c(">10", "8-10", "6-8",
        "4-6", "2-4", "1-2", "0-1", "-0-1", "-1-2", "-2-4", "-4-6", "-6-8", "-8-10",
        "<-10"), ordered = TRUE)) %>%
    dplyr::filter(diff_2C_cat != "NA")

PDSI_dur_4C_df <- raster::as.data.frame(raster::rasterToPoints(PDSI_dur_rob)) %>%
    dplyr::rename(sp_n = layer) %>%
    dplyr::filter(!is.na(sp_n)) %>%
    dplyr::mutate(diff_4C_cat = case_when(delta_dur_4C >= 10 ~ ">10", delta_dur_4C >=
        8 & delta_dur_4C < 10 ~ "8-10", delta_dur_4C >= 6 & delta_dur_4C < 8 ~ "6-8",
        delta_dur_4C >= 4 & delta_dur_4C < 6 ~ "4-6", delta_dur_4C >= 2 & delta_dur_4C <
            4 ~ "2-4", delta_dur_4C >= 1 & delta_dur_4C < 2 ~ "1-2", delta_dur_4C >
            0 & delta_dur_4C < 1 ~ "0-1", delta_dur_4C >= -1 & delta_dur_4C < 0 ~
            "-0-1", delta_dur_4C >= -2 & delta_dur_4C < -1 ~ "-1-2", delta_dur_4C >=
            -4 & delta_dur_4C < -2 ~ "-2-4", delta_dur_4C >= -6 & delta_dur_4C <
            -4 ~ "-4-6", delta_dur_4C >= -8 & delta_dur_4C < -6 ~ "-6-8", delta_dur_4C >=
            -10 & delta_dur_4C < -8 ~ "-8-10", delta_dur_4C < -10 ~ "<-10")) %>%
    dplyr::mutate(diff_4C_cat = factor(diff_4C_cat, levels = c(">10", "8-10", "6-8",
        "4-6", "2-4", "1-2", "0-1", "-0-1", "-1-2", "-2-4", "-4-6", "-6-8", "-8-10",
        "<-10"), ordered = TRUE)) %>%
    dplyr::filter(diff_4C_cat != "NA")

dur_2C_plot <- ggplot() + geom_raster(data = PDSI_dur_2C_df, aes(y = y, x = x, fill = diff_2C_cat)) +
    geom_polygon(data = world_rob, aes(x = long, y = lat, group = group), colour = "#64686b",
        fill = NA, size = 0.1) + scale_fill_manual(values = c("#67001F", "#B2182B",
    "#D6604D", "#F4A582", "#FDDBC7", "#FAE9DF", "#F7F7F7", "#dfebf2", "#D1E5F0")) +
    ggnewscale::new_scale("fill") + geom_raster(data = hill_df %>%
    filter(hill <= 0.645), aes(lon, lat, fill = hill, alpha = hill), show.legend = FALSE) +
    scale_fill_gradient(low = "black", high = "grey") + scale_alpha_continuous(trans = "reverse") +
    theme_void() + ylab(NULL) + xlab(NULL) + ggtitle(expression("Change in drought duration (" *
    Delta * "PDSI +2°C)")) + scale_y_continuous(limits = c(-6100000, 8500000), expand = c(0,
    0)) + scale_x_continuous(limits = c(-1.5e+07, 1.6e+07), expand = c(0, 0)) + theme(axis.title = element_blank(),
    axis.text = element_blank(), axis.ticks = element_blank(), plot.title = element_text(size = 10)) +
    coord_fixed(ratio = 1)  # fixed ratio

dur_4C_plot <- ggplot() + geom_raster(data = PDSI_dur_4C_df, aes(y = y, x = x, fill = diff_4C_cat)) +
    geom_polygon(data = world_rob, aes(x = long, y = lat, group = group), colour = "#64686b",
        fill = NA, size = 0.1) + scale_fill_manual(values = c("#67001F", "#B2182B",
    "#D6604D", "#F4A582", "#FDDBC7", "#FAE9DF", "#F7F7F7", "#dfebf2", "#D1E5F0")) +
    ggnewscale::new_scale("fill") + geom_raster(data = hill_df %>%
    filter(hill <= 0.645), aes(lon, lat, fill = hill, alpha = hill), show.legend = FALSE) +
    scale_fill_gradient(low = "black", high = "grey") + scale_alpha_continuous(trans = "reverse") +
    theme_void() + ylab(NULL) + xlab(NULL) + ggtitle(expression("Change in drought duration (" *
    Delta * "PDSI +4°C)")) + scale_y_continuous(limits = c(-6100000, 8500000), expand = c(0,
    0)) + scale_x_continuous(limits = c(-1.5e+07, 1.6e+07), expand = c(0, 0)) + theme(axis.title = element_blank(),
    axis.text = element_blank(), axis.ticks = element_blank(), plot.title = element_text(size = 10)) +
    coord_fixed(ratio = 1)  # fixed ratio

# 2C change - Fig S11b
dur_sp_2C <- data.frame(PDSI_dur_2C_df %>%
    dplyr::group_by(diff_2C_cat) %>%
    dplyr::summarise(species_n = length(sp_n[!is.na(sp_n)]))) %>%
    dplyr::mutate(all_freq = species_n/sum(species_n) * 100)

dur_sp_2C_plot <- dur_sp_2C %>%
    ggplot(aes(x = diff_2C_cat, y = all_freq, fill = diff_2C_cat)) + geom_bar(stat = "identity") +
    scale_fill_manual(values = c("#67001F", "#B2182B", "#D6604D", "#F4A582", "#FDDBC7",
        "#FAE9DF", "#F7F7F7", "#dfebf2", "#D1E5F0")) + geom_text(aes(label = round(all_freq,
    1)), vjust = -1, size = 2) + ylab("% species") + xlab("Months") + ylim(0, 50) +
    ggtitle("Grid cell occupied +2°C") + mytheme() + theme(plot.title = element_text(size = 10))

# 4C change - Fig S11d
dur_sp_4C <- data.frame(PDSI_dur_4C_df %>%
    dplyr::group_by(diff_4C_cat) %>%
    dplyr::summarise(species_n = length(sp_n[!is.na(sp_n)]))) %>%
    dplyr::mutate(all_freq = species_n/sum(species_n) * 100)

dur_sp_4C_plot <- dur_sp_4C %>%
    ggplot(aes(x = diff_4C_cat, y = all_freq, fill = diff_4C_cat)) + geom_bar(stat = "identity") +
    scale_fill_manual(values = c("#67001F", "#B2182B", "#D6604D", "#F4A582", "#FDDBC7",
        "#FAE9DF", "#F7F7F7", "#dfebf2", "#D1E5F0")) + geom_text(aes(label = round(all_freq,
    1)), vjust = -1, size = 2) + ylab("% species") + xlab("Months") + ylim(0, 50) +
    ggtitle("Grid cell occupied +4°C") + mytheme() + theme(plot.title = element_text(size = 10))

left_plot3 <- cowplot::plot_grid(dur_2C_plot + theme(legend.position = "none"), dur_4C_plot +
    theme(legend.position = "none"), ncol = 1, align = "h", axis = "bt", labels = c("a",
    "c"))

right_plot3 <- cowplot::plot_grid(dur_sp_2C_plot + theme(legend.position = "none"),
    dur_sp_4C_plot + theme(legend.position = "none"), ncol = 1, align = "h", axis = "bt",
    labels = c("b", "d"))

cowplot::plot_grid(left_plot3, right_plot3, ncol = 2, rel_widths = c(1, 0.7))

Extended Figure 4 - Water uptake

hydr_conditions <- list(hydration = setNames(c(70, 80, 90, 100), c(70, 80, 90, 100)))
wu_ce <- conditional_effects(wu_model, effects = "lnMass:hydration", int_conditions = hydr_conditions)

wu_ce <- data.frame(wu_ce[[1]]) %>%
    dplyr::rename(estimate = estimate__, hydration_cal = effect2__) %>%
    dplyr::mutate(mean_mass_g = exp(lnMass), hydration_cal = as.numeric(as.character(hydration_cal)))

wu_dat %>%
    ggplot() + geom_point(aes(x = mean_mass_g, y = mg_h_mean), size = 2, colour = "grey") +
    geom_line(data = wu_ce, aes(x = mean_mass_g, y = exp(estimate), group = hydration,
        colour = hydration), size = 1) + geom_text(data = wu_ce %>%
    filter(mean_mass_g == last(mean_mass_g)), aes(label = hydration, x = mean_mass_g +
    50, y = exp(estimate), hjust = -0.01), size = 3) + labs(x = "Body mass (g)",
    colour = "Initial hydration (%)") + ylab(expression("WU" ~ ("mg" ~ H[2] * O ~
    h^{
        "-1"
    }))) + scale_y_continuous(trans = scales::log_trans(), breaks = c(10, 100, 1000,
    10000, 1e+05), labels = c(10, 100, "1,000", "10,000", "100,000")) + scale_x_continuous(trans = "log10") +
    scale_colour_gradient2(low = "#0E3F5C", mid = "#2A6D7A", high = "#8FCCB4", midpoint = 85) +
    expand_limits(x = 500) + mytheme() + theme(legend.title = element_text(size = 8),
    legend.position = "bottom") + guides(colour = guide_colourbar(barheight = 0.5,
    barwidth = 10, title.position = "top"))


References

Anderson, R. C. O., Bovo, R. P., Eismann, C. E., Menegario, A. A. and Andrade, D. V. (2017). Not good, but not all bad: Dehydration effects on body fluids, organ masses, and water flux through the skin of Rhinella schneideri (Amphibia, Bufonidae). Physiological and Biochemical Zoology 90, 170191.
Baldwin, R. A. (1974). The water balance response of the pelvic “patch” of Bufo punctatus and Bufo boreas. Comparative Biochemistry and Physiology Part A: Physiology 47, 1285–1295.
Blaylock, L. A., Ruibal, R. and Kathryn, P.-A. (1976). Skin structure and wiping behavior of phyllomedusine frogs. Copeia 1976, 283–295.
Bovo, R. P., Simon, M. N., Lyra, M. L., Navas, C. A. and Andrade, D. V. Beyond janzen’s hypothesis: How amphibians that climb tropical mountains respond to climate variation.
Budyko, M. I. (1961). The heat balance of the earth’s surface. Soviet Geography 2, 3–13.
Buttemer, W. A. and Thomas, C. (2003). Influence of temperature on evaporative water loss and cutaneous resistance to water vapour diffusion in the orange-thighed frog (Litoria xanthomera). Australian Journal of Zoology 51, 111–118.
Feder, M. E. and Burggren, W. W. (1992). Environmental physiology of the amphibians. Chicago, USA: University of Chicago Press.
Gomez, N. A., Acosta, M., Zaidan III, F. and Lillywhite, H. B. (2006). Wiping behavior, skin resistance, and the metabolic response to dehydration in the arboreal frog Phyllomedusa hypochondrialis. Current Biology 79, 1058–1068.
Gouveia, S. F., Rafael, R. P., Rubalcaba, J. G., Da Silva, F. R., Maciel, N. M., Andrade, D. V. and Martinez, P. A. (2019). Biophysical modeling of water economy can explain geographic gradient of body size in anurans. The American Naturalist 193, 51–58.
Hillman, S. S., Withers, P. C., Drewes, R. C. and Hillyard, S. D. (2009). Ecological and environmental physiology of amphibians. New York, USA: Oxford University Press.
Jetz, W. and Pyron, R. A. (2018). The interplay of past diversification and evolutionary isolation with present imperilment across the amphibian tree of life. Nature Ecology & Evolution 2, 850–858.
Kearney, M. R. and Porter, W. P. (2017). NicheMapR–an R package for biophysical modelling: The microclimate model. Ecography 40, 664–674.
Kearney, M. R. and Porter, W. P. (2020). NicheMapR–an R package for biophysical modelling: The ectotherm and dynamic energy budget models. Ecography 43, 85–96.
Kearney, M. R., Phillips, B. L., Tracy, C. R., Christian, K. A., Betts, G. and Porter, W. P. (2008). Modelling species distributions without using species distributions: The cane toad in australia under current and future climates. Ecography 31, 423–434.
Kearney, M. R., Shamakhy, A., Tingley, R., Karoly, D. J., Hoffmann, A. A., Briggs, P. R. and Porter, W. P. (2014). Microclimate modelling at macro scales: A test of a general microclimate model integrated with gridded continental‐scale soil and weather data. Methods in Ecology and Evolution 5, 273–286.
Klein, W., Dabés, L., Bonfim, V. M. G., Magrini, L. and Napoli, M. F. (2016). Allometric relationships between cutaneous surface area and body mass in anuran amphibians. Zoologischer Anzeiger-A Journal of Comparative Zoology 263, 45–54.
Kobelt, F. and Linsenmair, K. E. (1986). Adaptations of the reed frog Hyperolius viridiflavus (amphibia, anura, hyperoliidae) to its arid environment i. The skin of Hyperolius viridiflavus nitidulus in wet and dry season conditions. Oecologia 68, 533–541.
Lillywhite, H. B. (2006). Water relations of tetrapod integument. Journal of Experimental Biology 209, 202–226.
McClanahan Jr, L. and Baldwin, R. (1969). Rate of water uptake through the integument of the desert toad, Bufo punctatus. Comparative Biochemistry and Physiology 28, 381–389.
Moen, D. S. and Wiens, J. J. (2017). Microhabitat and climatic niche change explain patterns of diversification among frog families. The American Naturalist 190, 29–44.
Monteith, John and Unsworth, M. (2013). Principles of environmental physics: Plants, animals, and the atmosphere. Oxford, UK: Academic Press.
Ouzzani, M., Hammady, H., Fedorowicz, Z. and Elmagarmid, A. (2016). Rayyan—a web and mobile app for systematic reviews. Systematic reviews 5, 1–10.
Palmer, W. C. (1965). Meteorological drought. Washington DC, USA: US Department of Commerce, Weather Bureau.
Pirtle, E. I., Tracy, C. R. and Kearney, R., Michael (2019). Hydroregulation: A neglected behavioral response of lizards to climate change? In Behavior of lizards, pp. 343–374. New York, USA: CRC Press.
Riddell, E. A., Apanovitch, E. K., Odom, J. P. and Sears, M. W. (2017). Physical calculations of resistance to water loss improve predictions of species range models. Ecological Monographs 87, 21–33.
Senzano, L. M., Bovo, R. P. and Andrade, D. V. (2022). Empirical estimation of skin resistance to water loss in amphibians: Agar evaluation as a non-resistance model to evaporation. Journal of Experimental Biology 225, jeb243941.
Spotila, J. R. and Berman, E. N. (1976). Determination of skin resistance and the role of the skin in controlling water loss in amphibians and reptiles. Comparative Biochemistry and Physiology Part A: Physiology 55, 407–411.
Stull, R. B. and Ahrens, C. D. (2000). Meteorology for scientists and engineers. Second edition. California, USA: Brooks/Cole.
Titon Jr, B. and Gomes, F. R. (2015). Relation between water balance and climatic variables associated with the geographical distribution of anurans. PLOS One 10, e0140761.
Titon Jr, B., Navas, C. A., Jim, J. and Gomes, F. R. (2010). Water balance and locomotor performance in three species of neotropical toads that differ in geographical distribution. Comparative Biochemistry and Physiology Part A: Molecular & Integrative Physiology 156, 129–135.
Tracy, C. R. (1976). A model of the dynamic exchanges of water and energy between a terrestrial amphibian and its environment. Ecological Monographs 46, 293–326.
Tracy, C. R., Welch, W. R., Pinshow, B., Kearney, M. R. and Porter, W. P. (2019). Properties of air: A manual for use in biophysical ecology.
Willumsen, N. J., Viborg, A. L. and Hillyard, S. D. (2007). Vascular aspects of water uptake mechanisms in the toad skin: Perfusion, diffusion, confusion. Comparative Biochemistry and Physiology Part A: Molecular & Integrative Physiology 148, 55–63.
Withers, P. C., Hillman, S. S., Drewes, R. and Sokol, O. (1982). Water loss and nitrogen excretion in sharp-nosed reed frogs (Hyperolius nasutus: Anura, Hyperoliidae). Journal of Experimental Biology 97, 335–343.
Withers, P. C., Hillman, S. S. and Drewes, R. C. (1984). Evaporative water loss and skin lipids of anuran amphibians. Journal of Experimental Zoology 232, 11–17.



Session Information

R version 4.2.2 (2022-10-31)

Platform: aarch64-apple-darwin20 (64-bit)

attached base packages: stats, graphics, grDevices, utils, datasets, methods and base

other attached packages: rasterSp(v.0.0.1), tmaptools(v.3.1-1), tmap(v.3.3-4), sf(v.1.0-14), raster(v.3.6-26), sp(v.2.1-1), ncdf4(v.1.21), NicheMapR(v.3.2.1), ggtree(v.3.4.1), phytools(v.1.9-16), maps(v.3.4.1.1), ape(v.5.7-1), performance(v.0.10.8), cmdstanr(v.0.5.3), rstan(v.2.32.3), StanHeaders(v.2.26.28), brms(v.2.20.4), Rcpp(v.1.0.11), ggnewscale(v.0.4.9), cowplot(v.1.1.1), RColorBrewer(v.1.1-3), colorspace(v.2.1-0), lubridate(v.1.9.3), forcats(v.1.0.0), stringr(v.1.5.0), dplyr(v.1.1.3), purrr(v.1.0.2), readr(v.2.1.4), tidyr(v.1.3.0), tibble(v.3.2.1), ggplot2(v.3.4.4), tidyverse(v.2.0.0), Matrix(v.1.5-4.1), pander(v.0.6.5) and knitr(v.1.45)

loaded via a namespace (and not attached): pacman(v.0.5.1), utf8(v.1.2.4), tidyselect(v.1.2.0), htmlwidgets(v.1.6.2), grid(v.4.2.2), combinat(v.0.0-8), munsell(v.0.5.0), codetools(v.0.2-19), units(v.0.8-4), DT(v.0.30), miniUI(v.0.1.1.1), withr(v.2.5.2), Brobdingnag(v.1.2-9), highr(v.0.10), rstudioapi(v.0.15.0), stats4(v.4.2.2), bayesplot(v.1.10.0), labeling(v.0.4.3), emmeans(v.1.8.9), polyclip(v.1.10-6), mnormt(v.2.1.1), optimParallel(v.1.0-2), farver(v.2.1.1), bridgesampling(v.1.1-2), coda(v.0.19-4), vctrs(v.0.6.4), treeio(v.1.20.1), generics(v.0.1.3), clusterGeneration(v.1.3.8), xfun(v.0.41), timechange(v.0.2.0), R6(v.2.5.1), markdown(v.1.11), doParallel(v.1.0.17), cachem(v.1.0.8), gridGraphics(v.0.5-1), promises(v.1.2.1), scales(v.1.2.1), gtable(v.0.3.4), lwgeom(v.0.2-13), processx(v.3.8.2), phangorn(v.2.11.1), rlang(v.1.1.2), scatterplot3d(v.0.3-44), splines(v.4.2.2), rgdal(v.1.6-7), lazyeval(v.0.2.2), dichromat(v.2.0-0.1), checkmate(v.2.3.0), inline(v.0.3.19), yaml(v.2.3.7), reshape2(v.1.4.4), abind(v.1.4-5), threejs(v.0.3.3), crosstalk(v.1.2.0), backports(v.1.4.1), httpuv(v.1.6.12), tensorA(v.0.36.2), tools(v.4.2.2), bookdown(v.0.36), ggplotify(v.0.1.2), ellipsis(v.0.3.2), jquerylib(v.0.1.4), posterior(v.1.5.0), proxy(v.0.4-27), ggridges(v.0.5.4), plyr(v.1.8.9), base64enc(v.0.1-3), classInt(v.0.4-10), ps(v.1.7.5), prettyunits(v.1.2.0), zoo(v.1.8-12), leafem(v.0.2.3), fs(v.1.6.3), magrittr(v.2.0.3), data.table(v.1.14.8), colourpicker(v.1.3.0), mvtnorm(v.1.2-3), matrixStats(v.1.0.0), hms(v.1.1.3), patchwork(v.1.1.3), shinyjs(v.2.1.0), mime(v.0.12), evaluate(v.0.23), xtable(v.1.8-4), XML(v.3.99-0.15), shinystan(v.2.6.0), leaflet(v.2.2.0), gridExtra(v.2.3), rstantools(v.2.3.1.1), compiler(v.4.2.2), KernSmooth(v.2.23-22), V8(v.4.4.0), crayon(v.1.5.2), htmltools(v.0.5.7), mgcv(v.1.9-0), ggfun(v.0.1.3), later(v.1.3.1), tzdb(v.0.4.0), aplot(v.0.2.2), expm(v.0.999-7), RcppParallel(v.5.1.7), DBI(v.1.1.3), tweenr(v.2.0.2), formatR(v.1.14), MASS(v.7.3-60), cli(v.3.6.1), quadprog(v.1.5-8), parallel(v.4.2.2), insight(v.0.19.6), igraph(v.1.5.1), pkgconfig(v.2.0.3), numDeriv(v.2016.8-1.1), terra(v.1.7-55), foreach(v.1.5.2), dygraphs(v.1.1.1.6), QuickJSR(v.1.0.7), bslib(v.0.5.1), estimability(v.1.4.1), yulab.utils(v.0.1.0), distributional(v.0.3.2), callr(v.3.7.3), digest(v.0.6.33), rmarkdown(v.2.25), fastmatch(v.1.1-4), leafsync(v.0.1.0), tidytree(v.0.4.5), curl(v.5.1.0), shiny(v.1.7.5.1), gtools(v.3.9.4), lifecycle(v.1.0.3), nlme(v.3.1-163), jsonlite(v.1.8.7), viridisLite(v.0.4.2), fansi(v.1.0.5), pillar(v.1.9.0), lattice(v.0.22-5), loo(v.2.6.0), fastmap(v.1.1.1), plotrix(v.3.8-3), pkgbuild(v.1.4.2), glue(v.1.6.2), xts(v.0.13.1), bayestestR(v.0.13.1), png(v.0.1-8), shinythemes(v.1.2.0), iterators(v.1.0.14), ggforce(v.0.4.1), class(v.7.3-22), stringi(v.1.7.12), sass(v.0.4.7), stars(v.0.6-4), memoise(v.2.0.1) and e1071(v.1.7-13)


  1. Hawkesbury Institute for the Environment, Western Sydney University, NSW 2753, Australia, ↩︎

LS0tCnRpdGxlOiAiV2lkZXNwcmVhZCBleHBvc3VyZSByaXNrIG9mIGFudXJhbnMgdG8gcmlzaW5nIGdsb2JhbCBkcnluZXNzIgpzdWJ0aXRsZTogIlN1cHBsZW1lbnRhcnkgSW5mb3JtYXRpb24iCmRhdGU6ICJgciBmb3JtYXQoU3lzLkRhdGUoKSwgJyVkLyVtLyVZJylgIgphdXRob3I6CiAgLSBOaWNob2xhcyBDLiBXdV5bSGF3a2VzYnVyeSBJbnN0aXR1dGUgZm9yIHRoZSBFbnZpcm9ubWVudCwgV2VzdGVybiBTeWRuZXkgVW5pdmVyc2l0eSwgTlNXIDI3NTMsIEF1c3RyYWxpYSwgbmljaG9sYXMud3UubnpAZ21haWwuY29tXQpvdXRwdXQ6CiAgYm9va2Rvd246Omh0bWxfZG9jdW1lbnQyOgogICAgY29kZV9kb3dubG9hZDogeWVzCiAgICBjb2RlX2ZvbGRpbmc6IGhpZGUKICAgIHRvYzogeWVzCiAgICB0b2NfZmxvYXQ6IHllcwogICAgaGlnaGxpZ2h0OiB0YW5nbwplZGl0b3Jfb3B0aW9uczoKICBjaHVua19vdXRwdXRfdHlwZTogY29uc29sZQpjc2w6IC4vYmliL3RoZS1qb3VybmFsLW9mLWV4cGVyaW1lbnRhbC1iaW9sb2d5LmNzbApiaWJsaW9ncmFwaHk6IC4vYmliL2Ryb3VnaHRfcmVmLmJpYgpsaW5rLWNpdGF0aW9uczogdHJ1ZQotLS0KCltHaXRIdWIgUmVwb3NpdG9yeV0oaHR0cHM6Ly9naXRodWIuY29tL25pY2hvbGFzd3Vuei9nbG9iYWwtZnJvZy1kcm91Z2h0KQpUaGUgUm1hcmtkb3duIGZpbGUgY2FuIGJlIGRvd25sb2FkZWQgZnJvbSB0aGUgKkNvZGUqIGRyb3AgZG93biBtZW51ICh0b3AgcmlnaHQpLgoKVGhpcyBzdXBwbGVtZW50YXJ5IGZpbGUgY29udGFpbnMgdGhlICpSKiB3b3JrZmxvdyBmb3IgcHJvY2Vzc2luZyBhbmQgYW5hbHlzaW5nIHRoZSByYXcgZGF0YSwgYW5kIGNyZWF0aW5nIGZpZ3VyZXMgZm9yIHRoZSBtYW51c2NyaXB0IHRpdGxlZCAiKipHbG9iYWwgdnVsbmVyYWJpbGl0eSBvZiBhbnVyYW5zIHRvIGRyb3VnaHQgYW5kIHdhcm1pbmcqKiIuCgpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0KbGlicmFyeShrbml0cikKa25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFLCBjYWNoZSA9IEZBTFNFLCB0aWR5ID0gVFJVRSwgbWVzc2FnZSA9IEZBTFNFLCB3YXJuaW5nID0gRkFMU0UpCm9wdGlvbnMoZHBseXIud2lkdGggPSBJbmYsIGtuaXRyLmthYmxlLk5BID0gIiIsIGRpZ2l0cyA9IDIpCgojIExvYWQgbGlicmFyeQpwYWNtYW46OnBfbG9hZChwYW5kZXIsIE1hdHJpeCwgdGlkeXZlcnNlLCBjb2xvcnNwYWNlLCBSQ29sb3JCcmV3ZXIsIGNvd3Bsb3QsIGdnbmV3c2NhbGUsIAogICAgICAgICAgICAgICBicm1zLCByc3RhbiwgY21kc3RhbnIsIHBlcmZvcm1hbmNlLCBhcGUsIHBoeXRvb2xzLCBnZ3RyZWUsIE5pY2hlTWFwUiwKICAgICAgICAgICAgICAgbmNkZjQsIHJhc3Rlciwgc2YsIHRtYXAsIHRtYXB0b29scywgcmFzdGVyU3ApCgojIEZ1bmN0aW9ucwpteXRoZW1lIDwtIGZ1bmN0aW9uKCkgewogIHRoZW1lX2J3KCkgKwogICAgdGhlbWUocGFuZWwuYm9yZGVyICAgICAgICAgID0gZWxlbWVudF9yZWN0KGZpbGwgPSBOQSwgY29sb3VyID0gImJsYWNrIiksCiAgICAgICAgICBwYW5lbC5ncmlkLm1ham9yICAgICAgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgICBwYW5lbC5ncmlkLm1pbm9yICAgICAgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgICBheGlzLmxpbmUgICAgICAgICAgICAgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgICBheGlzLnRpY2tzICAgICAgICAgICAgPSBlbGVtZW50X2xpbmUoY29sb3VyID0gImJsYWNrIiksCiAgICAgICAgICBheGlzLnRleHQgICAgICAgICAgICAgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwLCBjb2xvdXIgPSAiYmxhY2siKSwKICAgICAgICAgIGF4aXMudGl0bGUgICAgICAgICAgICA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApLAogICAgICAgICAgYXhpcy50aXRsZS55ICAgICAgICAgID0gZWxlbWVudF90ZXh0KHZqdXN0ID0gMyksCiAgICAgICAgICBheGlzLnRpdGxlLnggICAgICAgICAgPSBlbGVtZW50X3RleHQodmp1c3QgPSAtMSksCiAgICAgICAgICBwYW5lbC5iYWNrZ3JvdW5kICAgICAgPSBlbGVtZW50X3JlY3QoZmlsbCA9IE5BKSwKICAgICAgICAgIHBsb3QuYmFja2dyb3VuZCAgICAgICA9IGVsZW1lbnRfcmVjdChmaWxsID0gTkEsIGNvbG9yID0gTkEpLAogICAgICAgICAgcGxvdC5tYXJnaW4gICAgICAgICAgID0gdW5pdChjKDAuMiwgMC4yLCAwLjIsIDAuMiksIHVuaXRzID0gLCAiY20iKSwKICAgICAgICAgIGxlZ2VuZC5iYWNrZ3JvdW5kICAgICA9IGVsZW1lbnRfcmVjdChmaWxsID0gTkEsIGNvbG9yID0gTkEpLAogICAgICAgICAgbGVnZW5kLmJveC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGwgPSBOQSwgY29sb3IgPSBOQSksCiAgICAgICAgICBzdHJpcC50ZXh0LnggICAgICAgICAgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwLCBjb2xvciA9ICJibGFjayIsIGZhY2UgPSAiYm9sZCIpLAogICAgICAgICAgc3RyaXAuYmFja2dyb3VuZCAgICAgID0gZWxlbWVudF9yZWN0KGZpbGwgPSBOQSwgY29sb3IgPSBOQSksCiAgICAgICAgICBwbG90LnRpdGxlICAgICAgICAgICAgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKQogICAgKQp9ICMgc2V0IHVwIHBsb3QgdGhlbWUKCmFkZGJyYWNrZXQgPC0gZnVuY3Rpb24oeCl7cGFzdGUoIlsiLCB4LCAiXSIpfSAjIGFkZCBicmFja2V0cyBiZXR3ZWVuIHdvcmRzCgojIFNldCBvcHRpb25zIGluIFJzdGFuCnNldC5zZWVkKDEwKQpyc3Rhbl9vcHRpb25zKGF1dG9fd3JpdGUgPSBUUlVFKSAjIHRyYW5zbGF0ZSB0byBTVEFOIHBsYXRmb3JtIGZvciBydW5uaW5nIEJheWVzaWFuIG1vZGVsCm9wdGlvbnMobWMuY29yZXMgPSBwYXJhbGxlbDo6ZGV0ZWN0Q29yZXMoKSkgIyBkZXRlY3RzIGhvdyBtYW55IGNvcmVzIGF2YWlsYWJsZSB0byB1c2UKCiMgU2V0IGRpcmVjdG9yeQpzZXR3ZCgnL1VzZXJzL25pY2hvbGFzd3UvTGlicmFyeS9DbG91ZFN0b3JhZ2UvT25lRHJpdmUtV2VzdGVyblN5ZG5leVVuaXZlcnNpdHkvRHJvdWdodCBwcm9qZWN0LycpIAoKIyBTZXQgZmlsZSBwYXRocwpkYXRhX3BhdGggICAgIDwtIGZpbGUucGF0aCgiZGF0YSIpCnNwYXRpYWxfcGF0aCAgPC0gZmlsZS5wYXRoKCJTcGF0aWFsIGRhdGEiKQpyYXN0ZXJTcF9wYXRoIDwtICJyYXN0ZXJTcC9TcGVjaWVzRGF0YS8iCmBgYAoKCioqQWJicmV2aWF0aW9ucyoqCgotIEFJOiBBcmlkaXR5IEluZGV4Ci0gRVdMOiBFdmFwb3JhdGl2ZSB3YXRlciBsb3NzCi0gSVVDTjogSW50ZXJuYXRpb25hbCBVbmlvbiBmb3IgQ29uc2VydmF0aW9uIG9mIE5hdHVyZQotIFBEU0k6IFBhbG1lciBEcm91Z2h0IFNldmVyaXR5IEluZGV4Ci0gUFJJU01BOiBQcmVmZXJyZWQgUmVwb3J0aW5nIEl0ZW1zIGZvciBTeXN0ZW1hdGljIFJldmlld3MgYW5kIE1ldGEtQW5hbHlzZXMKLSBSSDogUmVsYXRpdmUgaHVtaWRpdHkKLSBTUFA6IFNoYXJlZCBTb2Npb2Vjb25vbWljIFBhdGh3YXkKLSBXVTogd2F0ZXIgdXB0YWtlCgojIFNwYXRpYWwgcmlzayB7LX0KCiMjIERlc2NyaXB0b3JzIHsudGFic2V0IC50YWJzZXQtZmFkZSAudGFic2V0LXBpbGxzIC19CgpUaGUgZm9sbG93aW5nIHNlcmllcyBvZiBjb2RlIGlzIHVzZWQgdG8gZXN0aW1hdGUgdGhlIHJpc2sgb2YgZXh0YW50IGFudXJhbnMgdG8gaW5jcmVhc2luZyBhcmlkaXR5IChBcmlkaXR5IEluZGV4OyBBSSkgYW5kIGRyb3VnaHQgKFBhbG1lciBEcm91Z2h0IFNldmVyaXR5IEluZGV4OyBQRFNJKS4gVGhlIEFJIHdhcyBjYXRlZ29yaXNlZCB0byBmaXZlIGNhdGVnb3JpZXMgYW5kIFRoZSBBSSB3YXMgY2F0ZWdvcmlzZWQgdG8gZml2ZSBjYXRlZ29yaWVzIChIdW1pZCwgRHJ5IHN1Yi1odW1pZCwgU2VtaS1hcmlkLCBBcmlkLCBhbmQgSHlwZXItYXJpZCkgYW5kIHRoZSBQRFNJIHdhcyBjYXRlZ29yaXNlZCB0byBzZXZlbiBjYXRlZ29yaWVzIChFeHRyZW1lbHkgbW9pc3QsIFZlcnkgbW9pc3QsIE1vZGVyYXRlIG1vaXN0LCBOb3JtYWwsIE1vZGVyYXRlIGRyb3VnaHQsIFNldmVyZSBkcm91Z2h0LCBFeHRyZW1lIGRyb3VnaHQpIGJhc2VkIG9uIGRlc2NyaXB0aW9ucyBmcm9tIEBCdWR5a28xOTYxIGFuZCBAUGFsbWVyMTk2NSwgcmVzcGVjdGl2ZWx5ICgqKlRhYmxlIFMxKiopLgoKR2VuZXJhbGlzZWQgZWNvbG9naWNhbCB0eXBlcyBvciDigJhlY290eXBl4oCZIHdlcmUgY2xhc3NpZmllZCBiYXNlZCBvbiBkZXNjcmlwdGlvbnMgZnJvbSBATW9lbjIwMTcgZm9jdXNpbmcgb24gYWR1bHQgYmVoYXZpb3VyIGFuZCBtaWNyb2hhYml0YXQgcHJlZmVyZW5jZXMgb3V0c2lkZSB0aGUgYnJlZWRpbmcgc2Vhc29uIGdpdmVuIHRoYXQgbWFueSBhbnVyYW5zIGJyZWVkIGluIHdhdGVyIGJ1dCBhcmUgbm90IGFkYXB0ZWQgdG8gbGl2ZSBpbiB3YXRlciBhbGwgeWVhciAoKipUYWJsZSBTMioqKS4KCiMjIyBUYWJsZSBTMSB7LnRhYnNldCAudGFic2V0LWZhZGUgLnRhYnNldC1waWxscyAtfSAKCioqVGFibGUgUzEqKiBBcmlkaXR5IGluZGV4IFtAQnVkeWtvMTk2MV0gYW5kIHRoZSBQYWxtZXIgRHJvdWdodCBTZXZlcml0eSBJbmRleCBbQFBhbG1lcjE5NjVdIGNhdGVnb3Jpc2VkLgoKYGBge3IgdGFibGUgUzEsIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0V9CmRhdGEuZnJhbWUoQUkgPSBjKCJIdW1pZCIsICJEcnkgc3ViLWh1bWlkIiwgIlNlbWktYXJpZCIsICJBcmlkIiwiSHlwZXItYXJpZCIsICIiLCAiIiksIAogICAgICAgICAgIFZhbHVlID0gYygi4omlIDAuNjUiLCAiMC41MCDigJMg4omkIDAuNjUiLCAiMC4yMCDigJMg4omkIDAuNTAiLCAiMC4wNSDigJMg4omkIDAuMjAiLCAiPCAwLjA1IiwgIiIsICIiKSwKICAgICAgICAgICBQRFNJID0gYygiRXh0cmVtZWx5IG1vaXN0IiwgIlZlcnkgbW9pc3QiLCAiTW9kZXJhdGUgbW9pc3QiLCAiTm9ybWFsIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTW9kZXJhdGUgZHJvdWdodCIsICJTZXZlcmUgZHJvdWdodCIsICIgRXh0cmVtZSBkcm91Z2h0IiksCiAgICAgICAgICAgVmFsdWUgPSBjKCLiiaUgNCIsICIzIOKAkyDiiaQgNCIsICIyIOKAkyDiiaQgMyIsICItMiDigJMg4omkIDIiLCAiLTMg4oCTIOKJpCAtMiIsICItNCDigJMg4omkIC0zIiwgIjwgLTQiKSkgJT4lCiAgZHBseXI6OnJlbmFtZSgiQXJpZGl0eSBpbmRleCAoQUkpIiAgICAgICAgICAgICAgICAgICA9IEFJLAogICAgICAgICAgICAgICAgIkFJIHZhbHVlIiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSBWYWx1ZSwKICAgICAgICAgICAgICAgICJQYWxtZXIgRHJvdWdodCBTZXZlcml0eSBJbmRleCAoUERTSSkiID0gUERTSSwKICAgICAgICAgICAgICAgICJQRFNJIFZhbHVlIiAgICAgICAgICAgICAgICAgICAgICAgICAgID0gVmFsdWUuMSkgJT4lCiAga25pdHI6OmthYmxlKCkgCmBgYAoKIyMjIFRhYmxlIFMyIHsudGFic2V0IC50YWJzZXQtZmFkZSAudGFic2V0LXBpbGxzIC19IAoKKipUYWJsZSBTMioqIE1pY3JvaGFiaXRhdCBwcmVmZXJlbmNlIG9yIGVjb3R5cGUgW0BNb2VuMjAxN10uCgpgYGB7ciB0YWJsZSBTMiwgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRX0KZGF0YS5mcmFtZShFY290eXBlID0gYygiQXF1YXRpYyIsICJBcmJvcmVhbCIsICJTZW1pLWFxdWF0aWMgIiwgIkdyb3VuZC1kd2VsbGluZyIsIkZvc3NvcmlhbCIsICJTdHJlYW0tZHdlbGxpbmciKSwgCiAgICAgICAgICAgRGVzY3JpcHRpb24gPSBjKCJBbG1vc3QgYWx3YXlzIGluIHdhdGVyLiIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAiQWJpbGl0eSB0byBjbGltYiB2ZWdldGF0aW9uIGFuZCBzcGVuZHMgYSBzdWJzdGFudGlhbCBhbW91bnQgb2YgdGltZSBhYm92ZSBncm91bmQgKGUuZy4gZm9yZXN0cywgb24gdG9wIG9mIHZlZ2V0YXRpb25zIGluIHdldGxhbmRzKS4iLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIlN0YXkgbmVhciB3YXRlciBib2RpZXMsIHVzdWFsbHkgcGVybWFuZW50IHdhdGVyIChlLmcuIGdyb3VuZC1sZXZlbCB3ZXRsYW5kcykuIE9mdGVuIG9ic2VydmVkIGluIHdhdGVyIGFuZCBuZWFyYnkgdmVnZXRhdGlvbi4iLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIlRlcnJlc3RyaWFsIG9ubHksIG5vdCBhbHdheXMgbmVhciB3YXRlciBib2RpZXMsIGhvd2V2ZXIgYWx3YXlzIGluIGEgbW9pc3QgZW52aXJvbm1lbnQgKGUuZy4gZm9yZXN0IGxlYWYgbGl0dGVyLCBtb2lzdCBzb2lscywgc2NydWJsYW5kcywgZ3Jhc3NsYW5kKS4gU29tZXRpbWVzIGFib3ZlIGdyb3VuZCBhbmQgc29tZXRpbWVzIHNlbWktZm9zc29yaWFsLiBDYW4gYmUgY2xhc3NpZmllZCBhcyBicm9hZC4iLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIlRoZSBub24tYnJlZWRpbmcgc2Vhc29uIGlzIHNwZW50IHVuZGVyZ3JvdW5kIGluIGJ1cnJvd3MuIENhcGFibGUgb2YgYnVycm93aW5nIGFuZCBhZXN0aXZhdGluZy4iLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIlJlc3RyaWN0ZWQgdG8gbmVhciBmYXN0LWZsb3dpbmcgc3RyZWFtcyB1c3VhbGx5IG9uIHJvY2tzIG9yIHZlZ2V0YXRpb24gbmVhciBzdHJlYW1zLiIpKSAlPiUKICBrbml0cjo6a2FibGUoKSAKYGBgCgojIyBTcGVjaWVzIHJpY2huZXNzIHstfQoKQW51cmFuIChmcm9ncyBhbmQgdG9hZHMpICBkaXN0cmlidXRpb24gc2hhcGUgZmlsZXMgd2VyZSBvYnRhaW5lZCBmcm9tIHRoZSBJbnRlcm5hdGlvbmFsIFVuaW9uIGZvciBDb25zZXJ2YXRpb24gb2YgTmF0dXJlJ3MgUmVkIExpc3Qgb2YgVGhyZWF0ZW5lZCBTcGVjaWVzIChbSVVDTiBSZWQgTGlzdF0oaHR0cHM6Ly93d3cuaXVjbnJlZGxpc3Qub3JnL3Jlc291cmNlcy9zcGF0aWFsLWRhdGEtZG93bmxvYWQpOyBleHRyYWN0ZWQgb24gMTEvMDEvMjAyMSkuIFNwZWNpZXMgcmljaG5lc3Mgd2FzIGRlZmluZWQgYXMgdGhlIHN1bSBvZiBzcGVjaWVzIGluIGVhY2ggZ3JpZCBjZWxsICgwLjXCsCksIGJhc2VkIG9uIHRoZSBnZW9ncmFwaGljIHJhbmdlLCBhbmQgd2FzIGNhbGN1bGF0ZWQgdXNpbmcgdGhlIGByYXN0ZXJpemVJVUNOYCBhbmQgYGNhbGNTUmAgZnVuY3Rpb24gZnJvbSB0aGUgZnJvbSB0aGUgW3Jhc3RlclNwXShodHRwczovL2dpdGh1Yi5jb20vUlMtZWNvL3Jhc3RlclNwKSBwYWNrYWdlLiBFY290eXBlLXNwZWNpZmljIHNwZWNpZXMgcmljaG5lc3Mgd2FzIGFsc28gY2FsY3VsYXRlZC4KCmBgYHtyIHNwLCBtZXNzYWdlPUZBTFNFLCBjYWNoZT1UUlVFLCByZXN1bHRzPSJoaWRlIn0KZmlsZWRpciA8LSAicmFzdGVyU3AvIgoKIyBDbGVhbiByYXcgZGF0YQpmcm9nX2RhdCA8LSByZWFkLmNzdihmaWxlLnBhdGgoZGF0YV9wYXRoLCAiYW51cmFuX3NwZWNpZXNfbGlzdC5jc3YiKSkgJT4lCiAgZHBseXI6OnNlbGVjdChnZW51czpzdHJhdGVneSwgU1ZMX2NtOmJpbm9taWFsX3RyZWVfcGh5bG8pICU+JQogIGRwbHlyOjptdXRhdGUobG5TVkwgICAgICAgPSBsb2coU1ZMX2NtKSwKICAgICAgICAgICAgICAgIGxuTWFzcyAgICAgID0gbG9nKG1hc3NfZyksCiAgICAgICAgICAgICAgICBsbkFyZWEgICAgICA9IGxvZyhzaGFwZV9hcmVhKSwKICAgICAgICAgICAgICAgIElVQ04gICAgICAgID0gZmFjdG9yKElVQ04sIGxldmVscyA9IGMoIkxlYXN0IENvbmNlcm4iLCAiTmVhciBUaHJlYXRlbmVkIiwgIlZ1bG5lcmFibGUiLCAiRW5kYW5nZXJlZCIsICJDcml0aWNhbGx5IEVuZGFuZ2VyZWQiLCAiRXh0aW5jdCIpKSwKICAgICAgICAgICAgICAgIG9yZGVyX25hbWUgID0gZmFjdG9yKG9yZGVyX25hbWUpLAogICAgICAgICAgICAgICAgZmFtaWx5X25hbWUgPSBmYWN0b3IoZmFtaWx5X25hbWUpLAogICAgICAgICAgICAgICAgZWNvdHlwZSAgICAgPSBmYWN0b3IoZWNvdHlwZSkpICU+JQogIGRwbHlyOjpmaWx0ZXIob3JkZXJfbmFtZSA9PSAiQU5VUkEiICYgZWNvdHlwZSAhPSAiIiAmIElVQ04gIT0gIiIgJiBJVUNOICE9ICJFeHRpbmN0IikgJT4lCiAgZHJvcGxldmVscygpCgojIENvbnZlcnQgc2hhcGUgZmlsZXMgaW50byByYXN0ZXJzIGFuZCBzYXZlIHRvIGZpbGUgb25jZSAoZG93bmxvYWRlZCBzaGFwZSBmaWxlcyAwOC8wMS8yMDIwKQojIG9ubHkgZXh0cmFjdGVkIGRpc3RyaWJ1dGlvbiBvZiBuYXRpdmUgcmFuZ2UKI2FudXJhbl9yYXN0IDwtIHJhc3Rlcml6ZUlVQ04oZHNuID0gcGFzdGUwKGZpbGVkaXIsICJBTlVSQS9BTlVSQS5zaHAiKSwgcmVzb2x1dGlvbiA9IDAuNSwgc2Vhc29uYWwgPSBjKDEsIDIpLCBvcmlnaW4gPSAxLCBwcmVzZW5jZSA9IGMoMSwyKSwgc2F2ZSA9IFRSVUUsIHBhdGggPSBwYXN0ZTAocmFzdGVyU3BfcGF0aCkpCgojIENhbGN1bGF0ZSBhbnVyYW4gcmljaG5lc3MgYW5kIGJ5IGVjb3R5cGUgCiMgVGhlIGNhbGNTUiBmdW5jdGlvbiB1c2VzIGEgc3RlcHdpc2UgcHJvY2VkdXJlIHRvIGNhbGN1bGF0ZSB0aGUgc3VtIG9mIHNwZWNpZXMgZm9yIGVhY2ggZ3JpZCBjZWxsLgphbnVyYW5fc3IgICAgPC0gcmFzdGVyU3A6OmNhbGNTUihzcGVjaWVzX25hbWVzID0gZnJvZ19kYXQkYmlub21pYWxfSVVDTiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhdGggPSBwYXN0ZTAocmFzdGVyU3BfcGF0aCkpCmFxdWF0aWNfc3IgICA8LSByYXN0ZXJTcDo6Y2FsY1NSKHNwZWNpZXNfbmFtZXMgPSBmcm9nX2RhdFtmcm9nX2RhdCRlY290eXBlID09ICJBcXVhdGljIiwgImJpbm9taWFsX0lVQ04iXSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhdGggPSBwYXN0ZTAocmFzdGVyU3BfcGF0aCkpCmFyYm9yZWFsX3NyICA8LSByYXN0ZXJTcDo6Y2FsY1NSKHNwZWNpZXNfbmFtZXMgPSBmcm9nX2RhdFtmcm9nX2RhdCRlY290eXBlID09ICJBcmJvcmVhbCIsICJiaW5vbWlhbF9JVUNOIl0sIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXRoID0gcGFzdGUwKHJhc3RlclNwX3BhdGgpKQpmb3Nzb3JpYWxfc3IgPC0gcmFzdGVyU3A6OmNhbGNTUihzcGVjaWVzX25hbWVzID0gZnJvZ19kYXRbZnJvZ19kYXQkZWNvdHlwZSA9PSAiRm9zc29yaWFsIiwgImJpbm9taWFsX0lVQ04iXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGF0aCA9IHBhc3RlMChyYXN0ZXJTcF9wYXRoKSkKZ3JvdW5kX3NyICAgIDwtIHJhc3RlclNwOjpjYWxjU1Ioc3BlY2llc19uYW1lcyA9IGZyb2dfZGF0W2Zyb2dfZGF0JGVjb3R5cGUgPT0gIkdyb3VuZC1kd2VsbGluZyIsICJiaW5vbWlhbF9JVUNOIl0sIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXRoID0gcGFzdGUwKHJhc3RlclNwX3BhdGgpKQpzZW1pX2FxX3NyICAgPC0gcmFzdGVyU3A6OmNhbGNTUihzcGVjaWVzX25hbWVzID0gZnJvZ19kYXRbZnJvZ19kYXQkZWNvdHlwZSA9PSAiU2VtaS1hcXVhdGljIiwgImJpbm9taWFsX0lVQ04iXSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhdGggPSBwYXN0ZTAocmFzdGVyU3BfcGF0aCkpCnN0cmVhbV9zciAgICA8LSByYXN0ZXJTcDo6Y2FsY1NSKHNwZWNpZXNfbmFtZXMgPSBmcm9nX2RhdFtmcm9nX2RhdCRlY290eXBlID09ICJTdHJlYW0tZHdlbGxpbmciLCAiYmlub21pYWxfSVVDTiJdLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGF0aCA9IHBhc3RlMChyYXN0ZXJTcF9wYXRoKSkKCiMgQ29udmVydCByYXN0ZXIgdG8gbWF0cml4IHRoZW4gdG8gZGF0YSBmcmFtZQphbnVyYW5fc3JfZGYgICAgPC0gcmFzdGVyOjphcy5kYXRhLmZyYW1lKHJhc3Rlcjo6cmFzdGVyVG9Qb2ludHMoYW51cmFuX3NyKSkgJT4lIGRwbHlyOjpyZW5hbWUoc3BlY2llc19uID0gbGF5ZXIpCmFxdWF0aWNfc3JfZGYgICA8LSByYXN0ZXI6OmFzLmRhdGEuZnJhbWUocmFzdGVyOjpyYXN0ZXJUb1BvaW50cyhhcXVhdGljX3NyKSkgJT4lIGRwbHlyOjpyZW5hbWUoYXF1YXRpY19uID0gbGF5ZXIpCmFyYm9yZWFsX3NyX2RmICA8LSByYXN0ZXI6OmFzLmRhdGEuZnJhbWUocmFzdGVyOjpyYXN0ZXJUb1BvaW50cyhhcmJvcmVhbF9zcikpICU+JSBkcGx5cjo6cmVuYW1lKGFyYm9yZWFsX24gPSBsYXllcikKZm9zc29yaWFsX3NyX2RmIDwtIHJhc3Rlcjo6YXMuZGF0YS5mcmFtZShyYXN0ZXI6OnJhc3RlclRvUG9pbnRzKGZvc3NvcmlhbF9zcikpICU+JSBkcGx5cjo6cmVuYW1lKGZvc3NvcmlhbF9uID0gbGF5ZXIpCmdyb3VuZF9zcl9kZiAgICA8LSByYXN0ZXI6OmFzLmRhdGEuZnJhbWUocmFzdGVyOjpyYXN0ZXJUb1BvaW50cyhncm91bmRfc3IpKSAlPiUgZHBseXI6OnJlbmFtZShncm91bmRfbiA9IGxheWVyKQpzZW1pX2FxX3NyX2RmICAgPC0gcmFzdGVyOjphcy5kYXRhLmZyYW1lKHJhc3Rlcjo6cmFzdGVyVG9Qb2ludHMoc2VtaV9hcV9zcikpICU+JSBkcGx5cjo6cmVuYW1lKHNlbWlfYXFfbiA9IGxheWVyKQpzdHJlYW1fc3JfZGYgICAgPC0gcmFzdGVyOjphcy5kYXRhLmZyYW1lKHJhc3Rlcjo6cmFzdGVyVG9Qb2ludHMoc3RyZWFtX3NyKSkgJT4lIGRwbHlyOjpyZW5hbWUoc3RyZWFtX24gPSBsYXllcikKYGBgCgpUaGVyZSBhcmUgYHIgbGVuZ3RoKHVuaXF1ZShmcm9nX2RhdCRiaW5vbWlhbF9JVUNOKSlgIGFudXJhbiBzcGVjaWVzIGZyb20gdGhlIElVQ04gUmVkIExpc3QgdXNlZCBmb3IgdGhlIGFuYWx5c2lzLgoKIyMgQ2FsY3VsYXRlIEFJIGFuZCBQRFNJIHstfQoKSGlnaCByZXNvbHV0aW9uICh+NCBrbV4yXikgZ2xvYmFsIGRhdGFzZXQgb24gcHJlY2lwaXRhdGlvbiAobW0vbW9udGgpIGFuZCBwb3RlbnRpYWwgZXZhcG90cmFuc3BpcmF0aW9uIChtbS9tb250aCkgd2VyZSBvYnRhaW5lZCBmcm9tIEFiYXR6b2dsb3UgZXQgYWwuICgyMDE4KSB1bmRlciAxKSB0aGUgY3VycmVudCBjbGltYXRlICgxOTcw4oCTMjAwMCksIDIpIGFuIGludGVybWVkaWF0ZSBncmVlbmhvdXNlIGdhcyBlbWlzc2lvbiBzY2VuYXJpbyBvZiArMsKwQyAoU2hhcmVkIFNvY2lvZWNvbm9taWMgUGF0aHdheSAy4oCTNC41OyBTUFAy4oCTNC41KSwgYW5kIDMpIGEgaGlnaCBncmVlbmhvdXNlIGdhcyBlbWlzc2lvbiBvciDigJxidXNpbmVzcy1hcy11c3VhbOKAnSBzY2VuYXJpbyBvZiArNMKwQyAoU1NQNeKAkzguNSkgYnkgMjA4MOKAkzIwOTkgKCoqRmlnLiBTMWHigJNmKiopLiAKCldlIG9idGFpbmVkIGEgc2VsZi1jYWxpYnJhdGVkIFBEU0kgd2l0aCBQZW5tYW7igJNNb250ZWl0aCBwb3RlbnRpYWwgZXZhcG90cmFuc3BpcmF0aW9uIHJlcHJlc2VudGluZyB0aGUgY3VycmVudCBjbGltYXRlICgxOTcw4oCTMjAwMCkgYW5kIGFuIGludGVybWVkaWF0ZSBhbmQgaGlnaCBlbWlzc2lvbiBzY2VuYXJpbyBieSAyMDgw4oCTMjA5OSAoU1NQMuKAkzQuNSBhbmQgU1NQNS04LjUpIGZyb20gWmhhbyBhbmQgRGFpICgyMDIyKS4gVGhlIFNTUDLigJM0LjUgYW5kIFNTUDXigJM4LjUgc2NlbmFyaW9zIHdlcmUgYmFzZWQgb24gdGhlIGF2ZXJhZ2Ugb2YgMjUgQ01JUDYgbW9kZWxzIG9mIHByZWNpcGl0YXRpb24sIGV2YXBvdHJhbnNwaXJhdGlvbiwgc29pbCBtb2lzdHVyZSwgYW5kIHJ1bm9mZiAoRXlyaW5nIGV0IGFsLiwgMjAxNiksIHdoZXJlIHRoZSBtZWFuIGFubnVhbCBzdXJmYWNlIHRlbXBlcmF0dXJlIGlzIGV4cGVjdGVkIHRvIGluY3JlYXNlIGJ5IDIuN8KwQyAoMi4x4oCTMy41wrBDIHJhbmdlKSBhbmQgNC40wrBDICgzLjPigJM1LjfCsEMgcmFuZ2UpLCByZXNwZWN0aXZlbHkgYnkgMjA4MOKAkzIxMDAgKElQQ0MsIDIwMjEpLgoKYGBge3IgY2xpbSBkYXQsIG1lc3NhZ2U9RkFMU0UsIGNhY2hlPVRSVUUsIHJlc3VsdHM9ImhpZGUifQojIEltcG9ydCB0aGUgZG93bmxvYWRlZCBmaWxlcwpwcHRfcmFzdCA8LSByYXN0ZXI6OnByb2plY3RSYXN0ZXIocmFzdGVyOjpzdGFjayh4ID0gZmlsZS5wYXRoKHNwYXRpYWxfcGF0aCwgJ1RlcnJhQ2xpbWF0ZTE5ODEyMDEwX3BwdC5uYycpKSwgYW51cmFuX3NyKSAjIFByZWNpcGl0YXRpb24geWVhciAxOTgxLTIwMTAgLSBQciAobW0pCnBldF9yYXN0IDwtIHJhc3Rlcjo6cHJvamVjdFJhc3RlcihyYXN0ZXI6OnN0YWNrKHggPSBmaWxlLnBhdGgoc3BhdGlhbF9wYXRoLCAnVGVycmFDbGltYXRlMTk4MTIwMTBfcGV0Lm5jJykpLCBhbnVyYW5fc3IpICMgRXZhcG90cmFuc3BpcmF0aW9uIDE5ODEtMjAxMCAtIEVUMCAobW0pCgojICsyQyBhbmQgKzRDIGZ1dHVyZSBzY2VuYXJpb3MgCnBwdF8yQ19yYXN0IDwtIHJhc3Rlcjo6cHJvamVjdFJhc3RlcihyYXN0ZXI6OnN0YWNrKHggPSBmaWxlLnBhdGgoc3BhdGlhbF9wYXRoLCAnVGVycmFDbGltYXRlMkNfcHB0Lm5jJykpLCBhbnVyYW5fc3IpCnBldF8yQ19yYXN0IDwtIHJhc3Rlcjo6cHJvamVjdFJhc3RlcihyYXN0ZXI6OnN0YWNrKHggPSBmaWxlLnBhdGgoc3BhdGlhbF9wYXRoLCAnVGVycmFDbGltYXRlMkNfcGV0Lm5jJykpLCBhbnVyYW5fc3IpCnBwdF80Q19yYXN0IDwtIHJhc3Rlcjo6cHJvamVjdFJhc3RlcihyYXN0ZXI6OnN0YWNrKHggPSBmaWxlLnBhdGgoc3BhdGlhbF9wYXRoLCAnVGVycmFDbGltYXRlNENfcHB0Lm5jJykpLCBhbnVyYW5fc3IpCnBldF80Q19yYXN0IDwtIHJhc3Rlcjo6cHJvamVjdFJhc3RlcihyYXN0ZXI6OnN0YWNrKHggPSBmaWxlLnBhdGgoc3BhdGlhbF9wYXRoLCAnVGVycmFDbGltYXRlNENfcGV0Lm5jJykpLCBhbnVyYW5fc3IpCgojIE9idGFpbiBtZWFuIHZhbHVlcyBmcm9tIDE5ODEtMjAxMApwcHRfbWVhbl9yYXN0ICAgIDwtIHJhc3Rlcjo6Y2FsYyhwcHRfcmFzdCwgZnVuID0gbWVhbiwgbmEucm0gPSBUUlVFKQpwZXRfbWVhbl9yYXN0ICAgIDwtIHJhc3Rlcjo6Y2FsYyhwZXRfcmFzdCwgZnVuID0gbWVhbiwgbmEucm0gPSBUUlVFKSAKcHB0XzJDX21lYW5fcmFzdCA8LSByYXN0ZXI6OmNhbGMocHB0XzJDX3Jhc3QsIGZ1biA9IG1lYW4sIG5hLnJtID0gVFJVRSkgCnBldF8yQ19tZWFuX3Jhc3QgPC0gcmFzdGVyOjpjYWxjKHBldF8yQ19yYXN0LCBmdW4gPSBtZWFuLCBuYS5ybSA9IFRSVUUpCnBwdF80Q19tZWFuX3Jhc3QgPC0gcmFzdGVyOjpjYWxjKHBwdF80Q19yYXN0LCBmdW4gPSBtZWFuLCBuYS5ybSA9IFRSVUUpCnBldF80Q19tZWFuX3Jhc3QgPC0gcmFzdGVyOjpjYWxjKHBldF80Q19yYXN0LCBmdW4gPSBtZWFuLCBuYS5ybSA9IFRSVUUpIAoKIyBPYnRhaW4gbWVhbiB2YWx1ZXMgZnJvbSAxMC15ZWFyIG1vbnRobHkgUERTSQpQRFNJX3NzcDI0NV9yYXN0IDwtIHJhc3Rlcjo6c3RhY2soeCA9IGZpbGUucGF0aChzcGF0aWFsX3BhdGgsICAncGRzaXNjLm1vbnRobHkuMTkwMC0yMTAwLnIyLjV4Mi41LkVuc0F2ZzI1TW9kZWxzLlRQMi5pcGUtMi5zc3AyNDUubmMnKSkKUERTSV9zc3A1ODVfcmFzdCA8LSByYXN0ZXI6OnN0YWNrKHggPSBmaWxlLnBhdGgoc3BhdGlhbF9wYXRoLCAgJ3Bkc2lzYy5tb250aGx5LjE5MDAtMjEwMC5yMi41eDIuNS5FbnNBdmcyNU1vZGVscy5UUDIuaXBlLTIuc3NwNTg1Lm5jJykpCgpQRFNJX2N1cl9yYXN0IDwtIHJhc3Rlcjo6c3Vic2V0KFBEU0lfc3NwMjQ1X3Jhc3QsIGdyZXAoIlgxOTcuKnxYMTk4Lip8WDE5OS4qIiwgbmFtZXMoUERTSV9zc3AyNDVfcmFzdCksIHZhbHVlID0gVCkpClBEU0lfMkNfcmFzdCAgPC0gcmFzdGVyOjpzdWJzZXQoUERTSV9zc3AyNDVfcmFzdCwgZ3JlcCgiWDIwNy4qfFgyMDguKnxYMjA5LioiLCBuYW1lcyhQRFNJX3NzcDI0NV9yYXN0KSwgdmFsdWUgPSBUKSkKUERTSV80Q19yYXN0ICA8LSByYXN0ZXI6OnN1YnNldChQRFNJX3NzcDU4NV9yYXN0LCBncmVwKCJYMjA3Lip8WDIwOC4qfFgyMDkuKiIsIG5hbWVzKFBEU0lfc3NwNTg1X3Jhc3QpLCB2YWx1ZSA9IFQpKQoKUERTSV9jdXJfbWVhbl9yYXN0IDwtIHJhc3Rlcjo6Y2FsYyhQRFNJX2N1cl9yYXN0LCBmdW4gPSBtZWFuLCBuYS5ybSA9IFRSVUUpClBEU0lfMkNfbWVhbl9yYXN0ICA8LSByYXN0ZXI6OmNhbGMoUERTSV8yQ19yYXN0LCBmdW4gPSBtZWFuLCBuYS5ybSA9IFRSVUUpIApQRFNJXzRDX21lYW5fcmFzdCAgPC0gcmFzdGVyOjpjYWxjKFBEU0lfNENfcmFzdCwgZnVuID0gbWVhbiwgbmEucm0gPSBUUlVFKSAKCiMgQ2FsY3VsYXRlIGFyaWRpdHkgaW5kZXggW1ByZWNpcGl0YXRpb24gKHBwdCkgLyBFdmFwb3RyYW5zcGlyYXRpb24gKHBldCldCmFpX3Jhc3QgICAgPC0gcmFzdGVyOjpvdmVybGF5KHggPSBwcHRfbWVhbl9yYXN0LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeSA9IHBldF9tZWFuX3Jhc3QsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmdW4gPSBmdW5jdGlvbih4LCB5KSB7cmV0dXJuKHggLyB5KX0pCmFpXzJDX3Jhc3QgPC0gcmFzdGVyOjpvdmVybGF5KHggPSBwcHRfMkNfbWVhbl9yYXN0LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeSA9IHBldF8yQ19tZWFuX3Jhc3QsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmdW4gPSBmdW5jdGlvbih4LCB5KSB7cmV0dXJuKHggLyB5KX0pIAphaV80Q19yYXN0IDwtIHJhc3Rlcjo6b3ZlcmxheSh4ID0gcHB0XzRDX21lYW5fcmFzdCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHkgPSBwZXRfNENfbWVhbl9yYXN0LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZnVuID0gZnVuY3Rpb24oeCwgeSkge3JldHVybih4IC8geSl9KSAKCiMgQ2FsY3VsYXRlIGNoYW5nZSBpbiBQRFNJCiMgUmVwcm9qZWN0IGludGVuc2l0eSByYXN0ZXIgdG8gbWF0Y2ggYW51cmFuX3NyClBEU0lfY3VyX21lYW5fcmFzdCA8LSByYXN0ZXI6OnByb2plY3RSYXN0ZXIoUERTSV9jdXJfbWVhbl9yYXN0LCBhbnVyYW5fc3IpClBEU0lfMkNfbWVhbl9yYXN0ICA8LSByYXN0ZXI6OnByb2plY3RSYXN0ZXIoUERTSV8yQ19tZWFuX3Jhc3QsIGFudXJhbl9zcikKUERTSV80Q19tZWFuX3Jhc3QgIDwtIHJhc3Rlcjo6cHJvamVjdFJhc3RlcihQRFNJXzRDX21lYW5fcmFzdCwgYW51cmFuX3NyKQoKUERTSV8yQ19kaWZmX3Jhc3QgPC0gcmFzdGVyOjpvdmVybGF5KHggPSBQRFNJX2N1cl9tZWFuX3Jhc3QsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeSA9IFBEU0lfMkNfbWVhbl9yYXN0LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZ1biA9IGZ1bmN0aW9uKHgsIHkpIHtyZXR1cm4oeSAtIHgpfSkgClBEU0lfNENfZGlmZl9yYXN0IDwtIHJhc3Rlcjo6b3ZlcmxheSh4ID0gUERTSV9jdXJfbWVhbl9yYXN0LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHkgPSBQRFNJXzRDX21lYW5fcmFzdCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmdW4gPSBmdW5jdGlvbih4LCB5KSB7cmV0dXJuKHkgLSB4KX0pIAoKIyBDb252ZXJ0IHJhc3RlciB0byBtYXRyaXggdGhlbiB0byBkYXRhIGZyYW1lCmFpX2RmICAgIDwtIHJhc3Rlcjo6YXMuZGF0YS5mcmFtZShyYXN0ZXI6OnJhc3RlclRvUG9pbnRzKGFpX3Jhc3QpKQphaV8yQ19kZiA8LSByYXN0ZXI6OmFzLmRhdGEuZnJhbWUocmFzdGVyOjpyYXN0ZXJUb1BvaW50cyhhaV8yQ19yYXN0KSkKYWlfNENfZGYgPC0gcmFzdGVyOjphcy5kYXRhLmZyYW1lKHJhc3Rlcjo6cmFzdGVyVG9Qb2ludHMoYWlfNENfcmFzdCkpCgpQRFNJXzJDX2RpZmZfZGYgPC0gcmFzdGVyOjphcy5kYXRhLmZyYW1lKHJhc3Rlcjo6cmFzdGVyVG9Qb2ludHMoUERTSV8yQ19kaWZmX3Jhc3QpKQpQRFNJXzRDX2RpZmZfZGYgPC0gcmFzdGVyOjphcy5kYXRhLmZyYW1lKHJhc3Rlcjo6cmFzdGVyVG9Qb2ludHMoUERTSV80Q19kaWZmX3Jhc3QpKQoKIyBDb252ZXJ0IGFyaWRpdHkgaW5kZXggaW50byBjYXRlZ29yeQphaV9kZiA8LSBhaV9kZiAlPiUgCiAgIyBSZWNvZGUKICBkcGx5cjo6bXV0YXRlKGNhdGVnb3J5ID0gY2FzZV93aGVuKAogICAgaXMuaW5maW5pdGUobGF5ZXIpIH4gJ0h1bWlkJywKICAgIGxheWVyID49IDAuNjUgfiAnSHVtaWQnLCAgICAgICAgICAgICAKICAgIGxheWVyID49IDAuNSAmIGxheWVyIDwgMC42NSB+ICdEcnkgc3ViLWh1bWlkJywKICAgIGxheWVyID49IDAuMiAmIGxheWVyIDwgMC41IH4gJ1NlbWktYXJpZCcsIAogICAgbGF5ZXIgPj0gMC4wNSAmIGxheWVyIDwgMC4yIH4gJ0FyaWQnLCAKICAgIGxheWVyIDwgMC4wNSB+ICdIeXBlci1hcmlkJwogICkpICU+JSAKICAjIENvbnZlcnQgdG8gb3JkZXJlZCBmYWN0b3IKICBkcGx5cjo6bXV0YXRlKGNhdGVnb3J5ID0gZmFjdG9yKGNhdGVnb3J5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSBjKCdIeXBlci1hcmlkJywgJ0FyaWQnLCAnU2VtaS1hcmlkJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnRHJ5IHN1Yi1odW1pZCcsICdIdW1pZCcpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcmRlcmVkID0gVFJVRSkpCgphaV8yQ19kZiA8LSBhaV8yQ19kZiAlPiUgCiAgIyBSZWNvZGUKICBkcGx5cjo6bXV0YXRlKGNhdGVnb3J5ID0gY2FzZV93aGVuKAogICAgaXMuaW5maW5pdGUobGF5ZXIpIH4gJ0h1bWlkJywKICAgIGxheWVyID49IDAuNjUgfiAnSHVtaWQnLCAgICAgICAgICAgICAgICAgICAgICAgCiAgICBsYXllciA+PSAwLjUgJiBsYXllciA8IDAuNjUgfiAnRHJ5IHN1Yi1odW1pZCcsIAogICAgbGF5ZXIgPj0gMC4yICYgbGF5ZXIgPCAwLjUgfiAnU2VtaS1hcmlkJywgICAgICAKICAgIGxheWVyID49IDAuMDUgJiBsYXllciA8IDAuMiB+ICdBcmlkJywgICAKICAgIGxheWVyIDwgMC4wNSB+ICdIeXBlci1hcmlkJwogICkpICU+JSAKICAjIENvbnZlcnQgdG8gb3JkZXJlZCBmYWN0b3IKICBkcGx5cjo6bXV0YXRlKGNhdGVnb3J5ID0gZmFjdG9yKGNhdGVnb3J5LAogICAgICAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSBjKCdIeXBlci1hcmlkJywgJ0FyaWQnLCAnU2VtaS1hcmlkJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnRHJ5IHN1Yi1odW1pZCcsICdIdW1pZCcpLAogICAgICAgICAgICAgICAgICAgICAgICAgICBvcmRlcmVkID0gVFJVRSkpCgphaV80Q19kZiA8LSBhaV80Q19kZiAlPiUgCiAgIyBSZWNvZGUKICBkcGx5cjo6bXV0YXRlKGNhdGVnb3J5ID0gY2FzZV93aGVuKAogICAgaXMuaW5maW5pdGUobGF5ZXIpIH4gJ0h1bWlkJywKICAgIGxheWVyID49IDAuNjUgfiAnSHVtaWQnLCAgICAgICAgICAgICAgICAgICAgICAgCiAgICBsYXllciA+PSAwLjUgJiBsYXllciA8IDAuNjUgfiAnRHJ5IHN1Yi1odW1pZCcsIAogICAgbGF5ZXIgPj0gMC4yICYgbGF5ZXIgPCAwLjUgfiAnU2VtaS1hcmlkJywgICAgICAKICAgIGxheWVyID49IDAuMDUgJiBsYXllciA8IDAuMiB+ICdBcmlkJywgICAKICAgIGxheWVyIDwgMC4wNSB+ICdIeXBlci1hcmlkJwogICkpICU+JSAKICAjIENvbnZlcnQgdG8gb3JkZXJlZCBmYWN0b3IKICBkcGx5cjo6bXV0YXRlKGNhdGVnb3J5ID0gZmFjdG9yKGNhdGVnb3J5LAogICAgICAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSBjKCdIeXBlci1hcmlkJywgJ0FyaWQnLCAnU2VtaS1hcmlkJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnRHJ5IHN1Yi1odW1pZCcsICdIdW1pZCcpLAogICAgICAgICAgICAgICAgICAgICAgICAgICBvcmRlcmVkID0gVFJVRSkpCgojIENvbnZlcnQgUERTSSB0byBjYXRlZ29yeQpQRFNJXzJDX2RpZmZfZGYgPC0gUERTSV8yQ19kaWZmX2RmICU+JSAKICAjIFJlY29kZQogIGRwbHlyOjptdXRhdGUoY2hhbmdlXzJDID0gY2FzZV93aGVuKAogICAgbGF5ZXIgPj0gNCB+ICI0IiwgICAgICAgICAgICAgICAgCiAgICBsYXllciA+PSAzICYgbGF5ZXIgPCA0IH4gJzMnLAogICAgbGF5ZXIgPj0gMiAmIGxheWVyIDwgMyB+ICcyJywgCiAgICBsYXllciA+PSAxICYgbGF5ZXIgPCAyIH4gJzEnLCAgCiAgICBsYXllciA+PSAtMSAmIGxheWVyIDwgMSB+ICcwJywgIAogICAgbGF5ZXIgPj0gLTIgJiBsYXllciA8IC0xIH4gJy0xJywgCiAgICBsYXllciA+PSAtMyAmIGxheWVyIDwgLTIgfiAnLTInLCAKICAgIGxheWVyID49IC00ICYgbGF5ZXIgPCAtMyB+ICctMycsIAogICAgbGF5ZXIgPCAtNCB+ICctNCcKICApKSAlPiUgCiAgIyBDb252ZXJ0IHRvIG9yZGVyZWQgZmFjdG9yCiAgZHBseXI6Om11dGF0ZShjaGFuZ2VfMkMgPSBmYWN0b3IoY2hhbmdlXzJDLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldmVscyA9IGMoJy00JywgJy0zJywgJy0yJywgJy0xJywgJzAnLCAnMScsICcyJywgJzMnLCAnNCcpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9yZGVyZWQgPSBUUlVFKSkKClBEU0lfNENfZGlmZl9kZiA8LSBQRFNJXzRDX2RpZmZfZGYgJT4lIAogICMgUmVjb2RlCiAgZHBseXI6Om11dGF0ZShjaGFuZ2VfNEMgPSBjYXNlX3doZW4oCiAgICBsYXllciA+PSA0IH4gIjQiLCAgICAgICAgICAgICAgICAKICAgIGxheWVyID49IDMgJiBsYXllciA8IDQgfiAnMycsCiAgICBsYXllciA+PSAyICYgbGF5ZXIgPCAzIH4gJzInLCAKICAgIGxheWVyID49IDEgJiBsYXllciA8IDIgfiAnMScsICAKICAgIGxheWVyID49IC0xICYgbGF5ZXIgPCAxIH4gJzAnLCAgCiAgICBsYXllciA+PSAtMiAmIGxheWVyIDwgLTEgfiAnLTEnLCAKICAgIGxheWVyID49IC0zICYgbGF5ZXIgPCAtMiB+ICctMicsIAogICAgbGF5ZXIgPj0gLTQgJiBsYXllciA8IC0zIH4gJy0zJywgCiAgICBsYXllciA8IC00IH4gJy00JwogICkpICU+JSAKICAjIENvbnZlcnQgdG8gb3JkZXJlZCBmYWN0b3IKICBkcGx5cjo6bXV0YXRlKGNoYW5nZV80QyA9IGZhY3RvcihjaGFuZ2VfNEMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV2ZWxzID0gYygnLTQnLCAnLTMnLCAnLTInLCAnLTEnLCAnMCcsICcxJywgJzInLCAnMycsICc0JyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3JkZXJlZCA9IFRSVUUpKQpgYGAKCmBgYHtyIEZpZyBTMSwgbWVzc2FnZT1GQUxTRSwgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcuaGVpZ2h0PTYuNSwgZmlnLndpZHRoPTl9CiMgQ3JvcCBhbmQgbWFzawp3b3JsZCAgICAgIDwtIHJnZGFsOjpyZWFkT0dSKGZpbGUucGF0aChzcGF0aWFsX3BhdGgsICJuZV81MG1fbGFuZC9uZV81MG1fbGFuZC5zaHAiKSkKd29ybGRfc3BkZiA8LSBzcDo6U3BhdGlhbFBvbHlnb25zRGF0YUZyYW1lKHdvcmxkLCB3b3JsZEBkYXRhKSAKCiMgUHJlY2lwaXRhdGlvbgpwcHRfY3Vycl9wbG90IDwtIHJhc3Rlcjo6YXMuZGF0YS5mcmFtZShyYXN0ZXI6OnJhc3RlclRvUG9pbnRzKHBwdF9tZWFuX3Jhc3QpKSAlPiUKICBnZ3Bsb3QoKSArCiAgZ2VvbV9yYXN0ZXIoYWVzKHkgPSB5LCB4ID0geCwgZmlsbCA9IGxheWVyKSkgKwogIGdlb21fcG9seWdvbihkYXRhID0gd29ybGRfc3BkZiwgYWVzKHggPSBsb25nLCB5ID0gbGF0LCBncm91cCA9IGdyb3VwKSwgY29sb3VyID0gIiM2NDY4NmIiLCBmaWxsID0gTkEsIHNpemUgPSAwLjEpICsKICBzY2FsZV9maWxsX2NvbnRpbnVvdXNfc2VxdWVudGlhbChwYWxldHRlID0gIllsR25CdSIsIGxpbSA9IGMoMCwgNjUwKSwgbmFtZSA9ICJQcmVjaXBpdGF0aW9uIChtbSkiKSArCiAgZ2d0aXRsZSgiQ3VycmVudCAoMTk4MS0yMDEwKSIpICsKICBzY2FsZV95X2NvbnRpbnVvdXMobGltaXRzID0gYygtNjAsIDkwKSwgZXhwYW5kID0gYygwLCAwKSkgKwogIHNjYWxlX3hfY29udGludW91cyhsaW1pdHMgPSBjKC0xODAsIDE4MCksIGV4cGFuZCA9IGMoMCwgMCkpICsKICBndWlkZXMoZmlsbCA9IGd1aWRlX2NvbG91cmJhcihiYXJ3aWR0aCA9IDEwLCBiYXJoZWlnaHQgPSAwLjMsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVsLnBvc2l0aW9uID0gImJvdHRvbSIpKSArCiAgdGhlbWVfdm9pZCgpICsgeWxhYihOVUxMKSArIHhsYWIoTlVMTCkgKwogIHRoZW1lKGF4aXMudGl0bGUgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50ZXh0ID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIGF4aXMudGlja3MgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApLAogICAgICAgIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gOCksIAogICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iKSArCiAgY29vcmRfZml4ZWQocmF0aW8gPSAxKSAgCgpwcHRfMkNfcGxvdCA8LSByYXN0ZXI6OmFzLmRhdGEuZnJhbWUocmFzdGVyOjpyYXN0ZXJUb1BvaW50cyhwcHRfMkNfbWVhbl9yYXN0KSkgJT4lCiAgZ2dwbG90KCkgKwogIGdlb21fcmFzdGVyKGFlcyh5ID0geSwgeCA9IHgsIGZpbGwgPSBsYXllcikpICsKICBnZW9tX3BvbHlnb24oZGF0YSA9IHdvcmxkX3NwZGYsIGFlcyh4ID0gbG9uZywgeSA9IGxhdCwgZ3JvdXAgPSBncm91cCksIGNvbG91ciA9ICIjNjQ2ODZiIiwgZmlsbCA9IE5BLCBzaXplID0gMC4xKSArCiAgc2NhbGVfZmlsbF9jb250aW51b3VzX3NlcXVlbnRpYWwocGFsZXR0ZSA9ICJZbEduQnUiLCBsaW0gPSBjKDAsIDY1MCkpICsKICBnZ3RpdGxlKCIrMsKwQyAoMjA4MC0yMTAwKSIpICsKICBzY2FsZV95X2NvbnRpbnVvdXMobGltaXRzID0gYygtNjAsIDkwKSwgZXhwYW5kID0gYygwLCAwKSkgKwogIHNjYWxlX3hfY29udGludW91cyhsaW1pdHMgPSBjKC0xODAsIDE4MCksIGV4cGFuZCA9IGMoMCwgMCkpICsKICB0aGVtZV92b2lkKCkgKyB5bGFiKE5VTEwpICsgeGxhYihOVUxMKSArCiAgdGhlbWUoYXhpcy50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRleHQgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50aWNrcyA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCkpICsKICBjb29yZF9maXhlZChyYXRpbyA9IDEpCgpwcHRfNENfcGxvdCA8LSByYXN0ZXI6OmFzLmRhdGEuZnJhbWUocmFzdGVyOjpyYXN0ZXJUb1BvaW50cyhwcHRfNENfbWVhbl9yYXN0KSkgJT4lCiAgZ2dwbG90KCkgKwogIGdlb21fcmFzdGVyKGFlcyh5ID0geSwgeCA9IHgsIGZpbGwgPSBsYXllcikpICsKICBnZW9tX3BvbHlnb24oZGF0YSA9IHdvcmxkX3NwZGYsIGFlcyh4ID0gbG9uZywgeSA9IGxhdCwgZ3JvdXAgPSBncm91cCksIGNvbG91ciA9ICIjNjQ2ODZiIiwgZmlsbCA9IE5BLCBzaXplID0gMC4xKSArCiAgc2NhbGVfZmlsbF9jb250aW51b3VzX3NlcXVlbnRpYWwocGFsZXR0ZSA9ICJZbEduQnUiLCBsaW0gPSBjKDAsIDY1MCkpICsKICBnZ3RpdGxlKCIrNMKwQyAoMjA4MC0yMTAwKSIpICsKICBzY2FsZV95X2NvbnRpbnVvdXMobGltaXRzID0gYygtNjAsIDkwKSwgZXhwYW5kID0gYygwLCAwKSkgKwogIHNjYWxlX3hfY29udGludW91cyhsaW1pdHMgPSBjKC0xODAsIDE4MCksIGV4cGFuZCA9IGMoMCwgMCkpICsKICB0aGVtZV92b2lkKCkgKyB5bGFiKE5VTEwpICsgeGxhYihOVUxMKSArCiAgdGhlbWUoYXhpcy50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRleHQgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50aWNrcyA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCkpICsKICBjb29yZF9maXhlZChyYXRpbyA9IDEpICAKCnBwdF9sZWdlbmQgPC0gY293cGxvdDo6Z2V0X2xlZ2VuZChwcHRfY3Vycl9wbG90KQoKcHB0X3Byb3cgPC0gY293cGxvdDo6cGxvdF9ncmlkKHBwdF9jdXJyX3Bsb3QgKyB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpLCAKICAgICAgICAgICAgICAgICAgIHBwdF8yQ19wbG90ICsgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiksIAogICAgICAgICAgICAgICAgICAgcHB0XzRDX3Bsb3QgKyB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpLCAKICAgICAgICAgICAgICAgICAgIGFsaWduID0gInYiLCBuY29sID0gMywgbGFiZWxzID0gYygnYScsICdiJywgJ2MnKSkgCgpwcHRfcGxvdHMgPC0gY293cGxvdDo6cGxvdF9ncmlkKHBwdF9wcm93LCBwcHRfbGVnZW5kLCBuY29sID0gMSwgcmVsX2hlaWdodHMgPSBjKDEsIC4xKSkKCiMgRXZhcG90cmFuc3BpcmF0aW9uCnBldF9jdXJyX3Bsb3QgPC0gcmFzdGVyOjphcy5kYXRhLmZyYW1lKHJhc3Rlcjo6cmFzdGVyVG9Qb2ludHMocGV0X21lYW5fcmFzdCkpICU+JQogIGdncGxvdCgpICsKICBnZW9tX3Jhc3RlcihhZXMoeSA9IHksIHggPSB4LCBmaWxsID0gbGF5ZXIpKSArCiAgZ2VvbV9wb2x5Z29uKGRhdGEgPSB3b3JsZF9zcGRmLCBhZXMoeCA9IGxvbmcsIHkgPSBsYXQsIGdyb3VwID0gZ3JvdXApLCBjb2xvdXIgPSAiIzY0Njg2YiIsIGZpbGwgPSBOQSwgc2l6ZSA9IDAuMSkgKwogIHNjYWxlX2ZpbGxfY29udGludW91c19zZXF1ZW50aWFsKHBhbGV0dGUgPSAiUm9ja2V0IiwgbGltID0gYygwLCAzMDApLCBuYW1lID0gIkV2YXBvdHJhbnNwaXJhdGlvbiAobW0pIikgKwogIHNjYWxlX3lfY29udGludW91cyhsaW1pdHMgPSBjKC02MCwgOTApLCBleHBhbmQgPSBjKDAsIDApKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGxpbWl0cyA9IGMoLTE4MCwgMTgwKSwgZXhwYW5kID0gYygwLCAwKSkgKwogIGd1aWRlcyhmaWxsID0gZ3VpZGVfY29sb3VyYmFyKGJhcndpZHRoID0gMTAsIGJhcmhlaWdodCA9IDAuMywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWwucG9zaXRpb24gPSAiYm90dG9tIikpICsKICB0aGVtZV92b2lkKCkgKyB5bGFiKE5VTEwpICsgeGxhYihOVUxMKSArCiAgdGhlbWUoYXhpcy50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRleHQgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50aWNrcyA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCksCiAgICAgICAgbGVnZW5kLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSA4KSwgCiAgICAgICAgbGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIpICsKICBjb29yZF9maXhlZChyYXRpbyA9IDEpICAKCnBldF8yQ19wbG90IDwtIHJhc3Rlcjo6YXMuZGF0YS5mcmFtZShyYXN0ZXI6OnJhc3RlclRvUG9pbnRzKHBldF8yQ19tZWFuX3Jhc3QpKSAlPiUKICBnZ3Bsb3QoKSArCiAgZ2VvbV9yYXN0ZXIoYWVzKHkgPSB5LCB4ID0geCwgZmlsbCA9IGxheWVyKSkgKwogIGdlb21fcG9seWdvbihkYXRhID0gd29ybGRfc3BkZiwgYWVzKHggPSBsb25nLCB5ID0gbGF0LCBncm91cCA9IGdyb3VwKSwgY29sb3VyID0gIiM2NDY4NmIiLCBmaWxsID0gTkEsIHNpemUgPSAwLjEpICsKICBzY2FsZV9maWxsX2NvbnRpbnVvdXNfc2VxdWVudGlhbChwYWxldHRlID0gIlJvY2tldCIsIGxpbSA9IGMoMCwgMzAwKSkgKwogIHNjYWxlX3lfY29udGludW91cyhsaW1pdHMgPSBjKC02MCwgOTApLCBleHBhbmQgPSBjKDAsIDApKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGxpbWl0cyA9IGMoLTE4MCwgMTgwKSwgZXhwYW5kID0gYygwLCAwKSkgKwogIHRoZW1lX3ZvaWQoKSArIHlsYWIoTlVMTCkgKyB4bGFiKE5VTEwpICsKICB0aGVtZShheGlzLnRpdGxlID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIGF4aXMudGV4dCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRpY2tzID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSkgKwogIGNvb3JkX2ZpeGVkKHJhdGlvID0gMSkKCnBldF80Q19wbG90IDwtIHJhc3Rlcjo6YXMuZGF0YS5mcmFtZShyYXN0ZXI6OnJhc3RlclRvUG9pbnRzKHBldF80Q19tZWFuX3Jhc3QpKSAlPiUKICBnZ3Bsb3QoKSArCiAgZ2VvbV9yYXN0ZXIoYWVzKHkgPSB5LCB4ID0geCwgZmlsbCA9IGxheWVyKSkgKwogIGdlb21fcG9seWdvbihkYXRhID0gd29ybGRfc3BkZiwgYWVzKHggPSBsb25nLCB5ID0gbGF0LCBncm91cCA9IGdyb3VwKSwgY29sb3VyID0gIiM2NDY4NmIiLCBmaWxsID0gTkEsIHNpemUgPSAwLjEpICsKICBzY2FsZV9maWxsX2NvbnRpbnVvdXNfc2VxdWVudGlhbChwYWxldHRlID0gIlJvY2tldCIsIGxpbSA9IGMoMCwgMzAwKSkgKwogIHNjYWxlX3lfY29udGludW91cyhsaW1pdHMgPSBjKC02MCwgOTApLCBleHBhbmQgPSBjKDAsIDApKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGxpbWl0cyA9IGMoLTE4MCwgMTgwKSwgZXhwYW5kID0gYygwLCAwKSkgKwogIHRoZW1lX3ZvaWQoKSArIHlsYWIoTlVMTCkgKyB4bGFiKE5VTEwpICsKICB0aGVtZShheGlzLnRpdGxlID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIGF4aXMudGV4dCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRpY2tzID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSkgKwogIGNvb3JkX2ZpeGVkKHJhdGlvID0gMSkgIAoKcGV0X2xlZ2VuZCA8LSBjb3dwbG90OjpnZXRfbGVnZW5kKHBldF9jdXJyX3Bsb3QpCgpwZXRfcHJvdyA8LSBjb3dwbG90OjpwbG90X2dyaWQocGV0X2N1cnJfcGxvdCArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiksIAogICAgICAgICAgICAgICAgICAgcGV0XzJDX3Bsb3QgKyAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKSwgCiAgICAgICAgICAgICAgICAgICBwZXRfNENfcGxvdCArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiksIAogICAgICAgICAgICAgICAgICAgYWxpZ24gPSAidiIsIG5jb2wgPSAzLCBsYWJlbHMgPSBjKCdkJywgJ2UnLCAnZicpKSAKCnBldF9wbG90cyA8LSBjb3dwbG90OjpwbG90X2dyaWQocGV0X3Byb3csIHBldF9sZWdlbmQsIG5jb2wgPSAxLCByZWxfaGVpZ2h0cyA9IGMoMSwgLjEpKQoKIyBBcmlkaXR5IEluZGV4CmFyaWRfY29sIDwtIGMoJyM4RTA2M0InLCAnI0NCNkQ1MycsICcjRTk5QTJDJywgJyNGNUQ1NzknLCAnd2hpdGUnKQphaV9jdXJyX3Bsb3QgPC0gZ2dwbG90KCkgKwogIGdlb21fcmFzdGVyKGRhdGEgPSBhaV9kZiwgYWVzKHkgPSB5LCB4ID0geCwgZmlsbCA9IGNhdGVnb3J5KSkgKwogIGdlb21fcG9seWdvbihkYXRhID0gd29ybGRfc3BkZiwgYWVzKHggPSBsb25nLCB5ID0gbGF0LCBncm91cCA9IGdyb3VwKSwgY29sb3VyID0gIiM2NDY4NmIiLCBmaWxsID0gTkEsIHNpemUgPSAwLjEpICsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBhcmlkX2NvbCwKICAgICAgICAgICAgICAgICAgICBndWlkZSA9IGd1aWRlX2xlZ2VuZChyZXZlcnNlID0gVFJVRSksCiAgICAgICAgICAgICAgICAgICAgbmFtZSA9ICJBcmlkaXR5IEluZGV4IikgKwogIHlsYWIoTlVMTCkgKyB4bGFiKE5VTEwpICsKICBzY2FsZV95X2NvbnRpbnVvdXMobGltaXRzID0gYygtNjAsIDkwKSwgZXhwYW5kID0gYygwLCAwKSkgKwogIHNjYWxlX3hfY29udGludW91cyhsaW1pdHMgPSBjKC0xODAsIDE4MCksIGV4cGFuZCA9IGMoMCwgMCkpICsKICB0aGVtZV92b2lkKCkgKyAKICB0aGVtZShheGlzLnRpdGxlID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIGF4aXMudGV4dCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRpY2tzID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSwKICAgICAgICBsZWdlbmQudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgpLCAKICAgICAgICBsZWdlbmQua2V5LnNpemUgPSB1bml0KDAuMiwgJ2NtJyksCiAgICAgICAgbGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIpICsKICBjb29yZF9maXhlZChyYXRpbyA9IDEpCgphaV8yQ19wbG90IDwtIGdncGxvdCgpICsKICBnZW9tX3Jhc3RlcihkYXRhID0gYWlfMkNfZGYsIGFlcyh5ID0geSwgeCA9IHgsIGZpbGwgPSBjYXRlZ29yeSkpICsKICBnZW9tX3BvbHlnb24oZGF0YSA9IHdvcmxkX3NwZGYsIGFlcyh4ID0gbG9uZywgeSA9IGxhdCwgZ3JvdXAgPSBncm91cCksIGNvbG91ciA9ICIjNjQ2ODZiIiwgZmlsbCA9IE5BLCBzaXplID0gMC4xKSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYXJpZF9jb2wsCiAgICAgICAgICAgICAgICAgICAgZ3VpZGUgPSBndWlkZV9sZWdlbmQocmV2ZXJzZSA9IFRSVUUpLAogICAgICAgICAgICAgICAgICAgIG5hbWUgPSAiQXJpZGl0eSBJbmRleCIpICsKICB5bGFiKE5VTEwpICsgeGxhYihOVUxMKSArCiAgc2NhbGVfeV9jb250aW51b3VzKGxpbWl0cyA9IGMoLTYwLCA5MCksIGV4cGFuZCA9IGMoMCwgMCkpICsKICBzY2FsZV94X2NvbnRpbnVvdXMobGltaXRzID0gYygtMTgwLCAxODApLCBleHBhbmQgPSBjKDAsIDApKSArCiAgdGhlbWVfdm9pZCgpICsgCiAgdGhlbWUoYXhpcy50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRleHQgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50aWNrcyA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCkpICsKICBjb29yZF9maXhlZChyYXRpbyA9IDEpCgphaV80Q19wbG90IDwtIGdncGxvdCgpICsKICBnZW9tX3Jhc3RlcihkYXRhID0gYWlfNENfZGYsIGFlcyh5ID0geSwgeCA9IHgsIGZpbGwgPSBjYXRlZ29yeSkpICsKICBnZW9tX3BvbHlnb24oZGF0YSA9IHdvcmxkX3NwZGYsIGFlcyh4ID0gbG9uZywgeSA9IGxhdCwgZ3JvdXAgPSBncm91cCksIGNvbG91ciA9ICIjNjQ2ODZiIiwgZmlsbCA9IE5BLCBzaXplID0gMC4xKSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYXJpZF9jb2wsCiAgICAgICAgICAgICAgICAgICAgZ3VpZGUgPSBndWlkZV9sZWdlbmQocmV2ZXJzZSA9IFRSVUUpLAogICAgICAgICAgICAgICAgICAgIG5hbWUgPSAiQXJpZGl0eSBJbmRleCIpICsKICB5bGFiKE5VTEwpICsgeGxhYihOVUxMKSArCiAgc2NhbGVfeV9jb250aW51b3VzKGxpbWl0cyA9IGMoLTYwLCA5MCksIGV4cGFuZCA9IGMoMCwgMCkpICsKICBzY2FsZV94X2NvbnRpbnVvdXMobGltaXRzID0gYygtMTgwLCAxODApLCBleHBhbmQgPSBjKDAsIDApKSArCiAgdGhlbWVfdm9pZCgpICsgCiAgdGhlbWUoYXhpcy50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRleHQgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50aWNrcyA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCkpICsKICBjb29yZF9maXhlZChyYXRpbyA9IDEpCgphaV9sZWdlbmQgPC0gY293cGxvdDo6Z2V0X2xlZ2VuZChhaV9jdXJyX3Bsb3QpCgphaV9wcm93IDwtIGNvd3Bsb3Q6OnBsb3RfZ3JpZChhaV9jdXJyX3Bsb3QgKyB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpLCAKICAgICAgICAgICAgICAgICAgIGFpXzJDX3Bsb3QgKyAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKSwgCiAgICAgICAgICAgICAgICAgICBhaV80Q19wbG90ICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKSwgCiAgICAgICAgICAgICAgICAgICBhbGlnbiA9ICJ2IiwgbmNvbCA9IDMsIGxhYmVscyA9IGMoJ2cnLCAnaCcsICdpJykpIAoKYWlfcGxvdHMgPC0gY293cGxvdDo6cGxvdF9ncmlkKGFpX3Byb3csIGFpX2xlZ2VuZCwgbmNvbCA9IDEsIHJlbF9oZWlnaHRzID0gYygxLCAuMSkpCgpjb3dwbG90OjpwbG90X2dyaWQocHB0X3Bsb3RzLCBwZXRfcGxvdHMsIGFpX3Bsb3RzLCBuY29sID0gMSkKYGBgCgoqKkZpZy4gUzEuKiogQ2xpbWF0ZSBkYXRhIHVzZWQgdG8gY2FsY3VsYXRlIHRoZSBhcmlkaXR5IGluZGV4LiBNZWFuIHByZWNpcGl0YXRpb24gKG1tKSBmb3IgKCoqYSoqKSB0aGUgY3VycmVudCBzY2VuYXJpbyBmcm9tIDE5ODEtMjAxMCwgKCoqYioqKSB1bmRlciBhbiBpbnRlcm1lZGlhdGUgZW1pc3Npb24gc2NlbmFyaW8gKFNoYXJlZCBTb2Npb2Vjb25vbWljIFBhdGh3YXlzIDIgLSA0LjU7IFNTUDItNC41KSwgYW5kICgqKmMqKikgdW5kZXIgYSBoaWdoIGVtaXNzaW9uIHNjZW5hcmlvIChTU1A1LTguNSkgYnkgMjA4MC0yMTAwLiBNZWFuIHBvdGVudGlhbCBldmFwb3RyYW5zcGlyYXRpb24gKG1tKSBmb3IgKCoqZCoqKSB0aGUgY3VycmVudCBzY2VuYXJpbyBmcm9tIDE5ODEtMjAxMCwgKCoqZSoqKSB1bmRlciBhbiBpbnRlcm1lZGlhdGUgZW1pc3Npb24gc2NlbmFyaW8gKFNTUDItNC41KSwgYW5kICgqKmYqKikgdW5kZXIgYSBoaWdoIGVtaXNzaW9uIHNjZW5hcmlvIChTU1A1LTguNSkgYnkgMjA4MC0yMTAwLiBDYWxjdWxhdGVkIEFyaWRpdHkgSW5kZXggZm9yICgqKmcqKikgdGhlIGN1cnJlbnQgc2NlbmFyaW8gZnJvbSAxOTgxLTIwMTAsICgqKmgqKikgdW5kZXIgYW4gaW50ZXJtZWRpYXRlIGVtaXNzaW9uIHNjZW5hcmlvIChTU1AyLTQuNSksIGFuZCAoKippKiopIHVuZGVyIGEgaGlnaCBlbWVzc2lvbiBzY2VuYXJpbyAoU1NQNS04LjUpIGJ5IDIwODAtMjEwMC4gCgojIyBBSSByaXNrIHstfQoKVG8gZXhhbWluZSB0aGUgcmVsYXRpb25zaGlwIG9mIHNwZWNpZXMgcmljaG5lc3Mgd2l0aCBhcmlkaXR5LCB0aGUgbnVtYmVyIG9mIHNwZWNpZXMgcGVyIGdpcmQgY2VsbCB3YXMgb3ZlcmxhcHBlZCB3aXRoIHRoZSBhcmlkaXR5IHJhc3RlciBsYXllciwgd2hlcmUgZWFjaCBncmlkIHdhcyBhc3NpZ25lZCBhbiBBSSBjYXRlZ29yeS4gVGhlIGNoYW5nZSBpbiBzcGVjaWVzIHJpY2huZXNzIGJldHdlZW4gdGhlIGN1cnJlbnQgYW5kIHByb2plY3RlZCAoZWl0aGVyICsyIG9yICs0IMKwQyB3YXJtaW5nKSBBSSBjYXRlZ29yeSB3YXMgY2FsY3VsYXRlZCBhcyB0aGUgY2hhbmdlIGluIEFJIGNhdGVnb3J5IGdyaWRzIChyZXNvbHV0aW9uIDAuNcKwIGZvciBkZWNpbWFsIGRlZ3JlZSBjb29yZGluYXRlcykgb2NjdXBpZWQgYnkgYW51cmFucyByZWxhdGl2ZSB0byB0aGUgZnV0dXJlIHByb2plY3Rpb24uIEEgZGVjcmVhc2UgaW5kaWNhdGVzIHJlZHVjZWQgbnVtYmVyIG9mIHNwZWNpZXMgd2l0aCB0aGUgYXNzaWduZWQgQUkgY2F0ZWdvcnkgYW5kIHZpY2UgdmVyc2EuCgpgYGB7ciBBSX0KIyBNZXJnZSBhcmlkaXR5IGluZGV4LCArNEMgYW5kIGFtcGhpYmlhbiBzcGVjaWVzIHJpY2huZXNzCmFpX3NwX2RmIDwtIGFpX2RmICU+JSAKICBkcGx5cjo6ZnVsbF9qb2luKGFpXzJDX2RmLCBieSA9IGMoIngiICwieSIpKSAlPiUKICBkcGx5cjo6ZnVsbF9qb2luKGFpXzRDX2RmLCBieSA9IGMoIngiICwieSIpKSAlPiUKICBkcGx5cjo6ZnVsbF9qb2luKGFudXJhbl9zcl9kZiwgYnkgPSBjKCJ4IiAsInkiKSkgJT4lIAogIGRwbHlyOjpmdWxsX2pvaW4oYXF1YXRpY19zcl9kZiwgYnkgPSBjKCJ4IiAsInkiKSkgJT4lIAogIGRwbHlyOjpmdWxsX2pvaW4oYXJib3JlYWxfc3JfZGYsIGJ5ID0gYygieCIgLCJ5IikpICU+JSAKICBkcGx5cjo6ZnVsbF9qb2luKGZvc3NvcmlhbF9zcl9kZiwgYnkgPSBjKCJ4IiAsInkiKSkgJT4lIAogIGRwbHlyOjpmdWxsX2pvaW4oZ3JvdW5kX3NyX2RmLCBieSA9IGMoIngiICwieSIpKSAlPiUgCiAgZHBseXI6OmZ1bGxfam9pbihzZW1pX2FxX3NyX2RmLCBieSA9IGMoIngiICwieSIpKSAlPiUgCiAgZHBseXI6OmZ1bGxfam9pbihzdHJlYW1fc3JfZGYsIGJ5ID0gYygieCIgLCJ5IikpICU+JSAKICBkcGx5cjo6cmVuYW1lKGFyaWRpdHkgPSBsYXllci54LAogICAgICAgICAgICAgICAgYXJpZGl0eV8yQyA9IGxheWVyLnksCiAgICAgICAgICAgICAgICBhcmlkaXR5XzRDID0gbGF5ZXIsCiAgICAgICAgICAgICAgICBjYXRlZ29yeSA9IGNhdGVnb3J5LngsCiAgICAgICAgICAgICAgICBjYXRlZ29yeV8yQyA9IGNhdGVnb3J5LnksCiAgICAgICAgICAgICAgICBjYXRlZ29yeV80QyA9IGNhdGVnb3J5KSAlPiUKICBkcm9wX25hKGNhdGVnb3J5KQoKIyBDYWxjdWxhdGUgZ3JpZCBjZWxscyBvY2N1cGllZCBmb3IgY3VycmVudCBjbGltYXRlCmFpX3NwX3N1bSA8LSBkYXRhLmZyYW1lKGFpX3NwX2RmICU+JSAKICAgICAgICAgICAgICAgICAgICAgICAgICBkcGx5cjo6Z3JvdXBfYnkoY2F0ZWdvcnkpICU+JSAKICAgICAgICAgICAgICAgICAgICAgICAgICBkcGx5cjo6c3VtbWFyaXNlKHNwZWNpZXNfbiAgID0gbGVuZ3RoKHNwZWNpZXNfblshaXMubmEoc3BlY2llc19uKV0pLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXF1YXRpY19uICAgPSBsZW5ndGgoYXF1YXRpY19uWyFpcy5uYShhcXVhdGljX24pXSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcmJvcmVhbF9uICA9IGxlbmd0aChhcmJvcmVhbF9uWyFpcy5uYShhcmJvcmVhbF9uKV0pLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9zc29yaWFsX24gPSBsZW5ndGgoZm9zc29yaWFsX25bIWlzLm5hKGZvc3NvcmlhbF9uKV0pLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ3JvdW5kX24gICAgPSBsZW5ndGgoZ3JvdW5kX25bIWlzLm5hKGdyb3VuZF9uKV0pLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VtaV9hcV9uICAgPSBsZW5ndGgoc2VtaV9hcV9uWyFpcy5uYShzZW1pX2FxX24pXSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJlYW1fbiAgICA9IGxlbmd0aChzdHJlYW1fblshaXMubmEoc3RyZWFtX24pXSkpKSAlPiUKICBkcGx5cjo6bXV0YXRlKHNjZW5hcmlvID0gIkN1cnJlbnQiLAogICAgICAgICAgICAgICAgYWxsX2ZyZXEgICAgICAgPSBzcGVjaWVzX24gLyBzdW0oc3BlY2llc19uKSAqIDEwMCwKICAgICAgICAgICAgICAgIGFxdWF0aWNfZnJlcSAgID0gYXF1YXRpY19uIC8gc3VtKGFxdWF0aWNfbikgKiAxMDAsCiAgICAgICAgICAgICAgICBhcmJvcmVhbF9mcmVxICA9IGFyYm9yZWFsX24gLyBzdW0oYXJib3JlYWxfbikgKiAxMDAsCiAgICAgICAgICAgICAgICBmb3Nzb3JpYWxfZnJlcSA9IGZvc3NvcmlhbF9uIC8gc3VtKGZvc3NvcmlhbF9uKSAqIDEwMCwKICAgICAgICAgICAgICAgIGdyb3VuZF9mcmVxICAgID0gZ3JvdW5kX24gLyBzdW0oZ3JvdW5kX24pICogMTAwLAogICAgICAgICAgICAgICAgc2VtaV9hcV9mcmVxICAgPSBzZW1pX2FxX24gLyBzdW0oc2VtaV9hcV9uKSAqIDEwMCwKICAgICAgICAgICAgICAgIHN0cmVhbV9mcmVxICAgID0gc3RyZWFtX24gLyBzdW0oc3RyZWFtX24pICogMTAwKQoKIyBDYWxjdWxhdGUgZ3JpZCBjZWxscyBvY2N1cGllZCBmb3IgZnV0dXJlIGNsaW1hdGUKYWlfMkNfc3Bfc3VtIDwtIGRhdGEuZnJhbWUoYWlfc3BfZGYgJT4lIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRwbHlyOjpncm91cF9ieShjYXRlZ29yeV8yQykgJT4lIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRwbHlyOjpzdW1tYXJpc2Uoc3BlY2llc19uICAgPSBsZW5ndGgoc3BlY2llc19uWyFpcy5uYShzcGVjaWVzX24pXSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcXVhdGljX24gICA9IGxlbmd0aChhcXVhdGljX25bIWlzLm5hKGFxdWF0aWNfbildKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFyYm9yZWFsX24gID0gbGVuZ3RoKGFyYm9yZWFsX25bIWlzLm5hKGFyYm9yZWFsX24pXSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3Nzb3JpYWxfbiA9IGxlbmd0aChmb3Nzb3JpYWxfblshaXMubmEoZm9zc29yaWFsX24pXSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBncm91bmRfbiAgICA9IGxlbmd0aChncm91bmRfblshaXMubmEoZ3JvdW5kX24pXSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZW1pX2FxX24gICA9IGxlbmd0aChzZW1pX2FxX25bIWlzLm5hKHNlbWlfYXFfbildKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmVhbV9uICAgID0gbGVuZ3RoKHN0cmVhbV9uWyFpcy5uYShzdHJlYW1fbildKSkpICU+JQogIGRwbHlyOjptdXRhdGUoc2NlbmFyaW8gPSAiU1NQMjQ1IiwKICAgICAgICAgICAgICAgIGFsbF9mcmVxICAgICAgID0gc3BlY2llc19uIC8gc3VtKHNwZWNpZXNfbikgKiAxMDAsCiAgICAgICAgICAgICAgICBhcXVhdGljX2ZyZXEgICA9IGFxdWF0aWNfbiAvIHN1bShhcXVhdGljX24pICogMTAwLAogICAgICAgICAgICAgICAgYXJib3JlYWxfZnJlcSAgPSBhcmJvcmVhbF9uIC8gc3VtKGFyYm9yZWFsX24pICogMTAwLAogICAgICAgICAgICAgICAgZm9zc29yaWFsX2ZyZXEgPSBmb3Nzb3JpYWxfbiAvIHN1bShmb3Nzb3JpYWxfbikgKiAxMDAsCiAgICAgICAgICAgICAgICBncm91bmRfZnJlcSAgICA9IGdyb3VuZF9uIC8gc3VtKGdyb3VuZF9uKSAqIDEwMCwKICAgICAgICAgICAgICAgIHNlbWlfYXFfZnJlcSAgID0gc2VtaV9hcV9uIC8gc3VtKHNlbWlfYXFfbikgKiAxMDAsCiAgICAgICAgICAgICAgICBzdHJlYW1fZnJlcSAgICA9IHN0cmVhbV9uIC8gc3VtKHN0cmVhbV9uKSAqIDEwMCkgJT4lIAogIGRwbHlyOjpyZW5hbWUoY2F0ZWdvcnkgPSBjYXRlZ29yeV8yQykgCgphaV80Q19zcF9zdW0gPC0gZGF0YS5mcmFtZShhaV9zcF9kZiAlPiUgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZHBseXI6Omdyb3VwX2J5KGNhdGVnb3J5XzRDKSAlPiUgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZHBseXI6OnN1bW1hcmlzZShzcGVjaWVzX24gICA9IGxlbmd0aChzcGVjaWVzX25bIWlzLm5hKHNwZWNpZXNfbildKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFxdWF0aWNfbiAgID0gbGVuZ3RoKGFxdWF0aWNfblshaXMubmEoYXF1YXRpY19uKV0pLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJib3JlYWxfbiAgPSBsZW5ndGgoYXJib3JlYWxfblshaXMubmEoYXJib3JlYWxfbildKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvc3NvcmlhbF9uID0gbGVuZ3RoKGZvc3NvcmlhbF9uWyFpcy5uYShmb3Nzb3JpYWxfbildKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdyb3VuZF9uICAgID0gbGVuZ3RoKGdyb3VuZF9uWyFpcy5uYShncm91bmRfbildKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbWlfYXFfbiAgID0gbGVuZ3RoKHNlbWlfYXFfblshaXMubmEoc2VtaV9hcV9uKV0pLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyZWFtX24gICAgPSBsZW5ndGgoc3RyZWFtX25bIWlzLm5hKHN0cmVhbV9uKV0pKSkgJT4lCiAgZHBseXI6Om11dGF0ZShzY2VuYXJpbyA9ICJTU1A1ODUiLAogICAgICAgICAgICAgICAgYWxsX2ZyZXEgICAgICAgPSBzcGVjaWVzX24gLyBzdW0oc3BlY2llc19uKSAqIDEwMCwKICAgICAgICAgICAgICAgIGFxdWF0aWNfZnJlcSAgID0gYXF1YXRpY19uIC8gc3VtKGFxdWF0aWNfbikgKiAxMDAsCiAgICAgICAgICAgICAgICByYm9yZWFsX2ZyZXEgICA9IGFyYm9yZWFsX24gLyBzdW0oYXJib3JlYWxfbikgKiAxMDAsCiAgICAgICAgICAgICAgICBmb3Nzb3JpYWxfZnJlcSA9IGZvc3NvcmlhbF9uIC8gc3VtKGZvc3NvcmlhbF9uKSAqIDEwMCwKICAgICAgICAgICAgICAgIGdyb3VuZF9mcmVxICAgID0gZ3JvdW5kX24gLyBzdW0oZ3JvdW5kX24pICogMTAwLAogICAgICAgICAgICAgICAgc2VtaV9hcV9mcmVxICAgPSBzZW1pX2FxX24gLyBzdW0oc2VtaV9hcV9uKSAqIDEwMCwKICAgICAgICAgICAgICAgIHN0cmVhbV9mcmVxICAgID0gc3RyZWFtX24gLyBzdW0oc3RyZWFtX24pICogMTAwKSAlPiUgCiAgZHBseXI6OnJlbmFtZShjYXRlZ29yeSA9IGNhdGVnb3J5XzRDKQpgYGAKCiMjIFBEU0kgcmlzayB7LX0KCldpdGggYSBtb250aGx5IHByZWRpY3Rpb24gb2YgUERTSSBmcm9tIDE5NTAgdG8gMjEwMCBnbG9iYWxseSBhdmFpbGFibGUgZnJvbSBaaGFvIGFuZCBEYWkgKDIwMjIpLCB3ZSBjbGFzc2lmaWVkIGZ1dHVyZSBkcm91Z2h0IHJpc2sgaW4gdGhyZWUgd2F5czogMSkgaW5jcmVhc2UgaW4gZHJvdWdodCBpbnRlbnNpdHkgKG1hZ25pdHVkZSBjaGFuZ2UgaW4gUERTSSksIGluY3JlYXNlIGluIGRyb3VnaHQgZnJlcXVlbmN5IChtb250aGx5IFBEU0kgY291bnRzIGJlbG93IC0yIHBlciB5ZWFyKSwgaW5jcmVhc2UgaW4gZHVyYXRpb24gKG51bWJlciBvZiBjb25zZWN1dGl2ZSBtb250aHMgd2l0aCBQRFNJIHZhbHVlcyBiZWxvdyAtMikuIENoYW5nZSBpbiBkcm91Z2h0IGludGVuc2l0eSAozpRQRFNJW2ludGVuc2l0eV0pLCBmcmVxdWVuY3kgKM6UUERTSVtmcmVxdWVuY3ldKSwgIGFuZCBkdXJhdGlvbiAozpRQRFNJW2R1cmF0aW9uXSkgdW5kZXIgYSArMiBvciArNCDCsEMgd2FybWluZyBzY2VuYXJpbyAoMjA4MOKAkzIxMDApIHdhcyBjYWxjdWxhdGVkIHJlbGF0aXZlIHRvIHRoZSAxOTcw4oCTMjAwMCBtb250aGx5IGNsaW1hdG9sb2d5IHBlciBnaXJkIGNlbGwgKM6UUERTSSA9IFBEU0lbZnV0dXJlXSDigJMgUERTSVtjdXJyZW50XSkuIE5vdGUsIHRoZSB0ZW1wb3JhbCByZXNvbHV0aW9uIHdhcyBsaW1pdGVkIHRvIG1vbnRobHkgdmFyaWF0aW9uIGFzIHRoZSBQRFNJIHdhcyBkZXZlbG9wZWQgdG8gbW9uaXRvciBsb25nLXRlcm0gbWV0ZW9yb2xvZ2ljYWwgZHJvdWdodC4KCmBgYHtyIFBEU0kgaW50fQojIENoYW5nZSBpbiBQRFNJIGludGVuc2l0eSAKUERTSV9zcF9kZiA8LSBhbnVyYW5fc3JfZGYgJT4lIAogIGRwbHlyOjpmdWxsX2pvaW4oUERTSV8yQ19kaWZmX2RmLCBieSA9IGMoIngiICwieSIpKSAlPiUgCiAgZHBseXI6OmZ1bGxfam9pbihQRFNJXzRDX2RpZmZfZGYsIGJ5ID0gYygieCIgLCJ5IikpICU+JSAKICBkcGx5cjo6ZnVsbF9qb2luKGFxdWF0aWNfc3JfZGYsIGJ5ID0gYygieCIgLCJ5IikpICU+JSAKICBkcGx5cjo6ZnVsbF9qb2luKGFyYm9yZWFsX3NyX2RmLCBieSA9IGMoIngiICwieSIpKSAlPiUgCiAgZHBseXI6OmZ1bGxfam9pbihmb3Nzb3JpYWxfc3JfZGYsIGJ5ID0gYygieCIgLCJ5IikpICU+JSAKICBkcGx5cjo6ZnVsbF9qb2luKGdyb3VuZF9zcl9kZiwgYnkgPSBjKCJ4IiAsInkiKSkgJT4lIAogIGRwbHlyOjpmdWxsX2pvaW4oc2VtaV9hcV9zcl9kZiwgYnkgPSBjKCJ4IiAsInkiKSkgJT4lIAogIGRwbHlyOjpmdWxsX2pvaW4oc3RyZWFtX3NyX2RmLCBieSA9IGMoIngiICwieSIpKSAlPiUgCiAgZHBseXI6OnJlbmFtZShQRFNJXzJDID0gbGF5ZXIueCwKICAgICAgICAgICAgICAgIFBEU0lfNEMgPSBsYXllci55KSAlPiUKICBkcm9wX25hKGNoYW5nZV8yQykgJT4lCiAgZmlsdGVyKHNwZWNpZXNfbiAhPSAiTkEiKQoKIyBDYWxjdWxhdGUgZ3JpZCBjZWxscyBvY2N1cGllZCBmb3IgY3VycmVudCBjbGltYXRlClBEU0lfc3BfMkMgPC0gZGF0YS5mcmFtZShQRFNJX3NwX2RmICU+JSAKICAgICAgICAgICAgICAgICAgICAgICAgICAgZHBseXI6Omdyb3VwX2J5KGNoYW5nZV8yQykgJT4lIAogICAgICAgICAgICAgICAgICAgICAgICAgICBkcGx5cjo6c3VtbWFyaXNlKHNwZWNpZXNfbiAgID0gbGVuZ3RoKHNwZWNpZXNfblshaXMubmEoc3BlY2llc19uKV0pLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFxdWF0aWNfbiAgID0gbGVuZ3RoKGFxdWF0aWNfblshaXMubmEoYXF1YXRpY19uKV0pLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFyYm9yZWFsX24gID0gbGVuZ3RoKGFyYm9yZWFsX25bIWlzLm5hKGFyYm9yZWFsX24pXSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9zc29yaWFsX24gPSBsZW5ndGgoZm9zc29yaWFsX25bIWlzLm5hKGZvc3NvcmlhbF9uKV0pLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdyb3VuZF9uICAgID0gbGVuZ3RoKGdyb3VuZF9uWyFpcy5uYShncm91bmRfbildKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZW1pX2FxX24gICA9IGxlbmd0aChzZW1pX2FxX25bIWlzLm5hKHNlbWlfYXFfbildKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJlYW1fbiAgICA9IGxlbmd0aChzdHJlYW1fblshaXMubmEoc3RyZWFtX24pXSkpKSAlPiUKICBkcGx5cjo6bXV0YXRlKGFsbF9mcmVxICAgICAgID0gc3BlY2llc19uIC8gc3VtKHNwZWNpZXNfbikgKiAxMDAsCiAgICAgICAgICAgICAgICBhcXVhdGljX2ZyZXEgICA9IGFxdWF0aWNfbiAvIHN1bShhcXVhdGljX24pICogMTAwLAogICAgICAgICAgICAgICAgYXJib3JlYWxfZnJlcSAgPSBhcmJvcmVhbF9uIC8gc3VtKGFyYm9yZWFsX24pICogMTAwLAogICAgICAgICAgICAgICAgZm9zc29yaWFsX2ZyZXEgPSBmb3Nzb3JpYWxfbiAvIHN1bShmb3Nzb3JpYWxfbikgKiAxMDAsCiAgICAgICAgICAgICAgICBncm91bmRfZnJlcSAgICA9IGdyb3VuZF9uIC8gc3VtKGdyb3VuZF9uKSAqIDEwMCwKICAgICAgICAgICAgICAgIHNlbWlfYXFfZnJlcSAgID0gc2VtaV9hcV9uIC8gc3VtKHNlbWlfYXFfbikgKiAxMDAsCiAgICAgICAgICAgICAgICBzdHJlYW1fZnJlcSAgICA9IHN0cmVhbV9uIC8gc3VtKHN0cmVhbV9uKSAqIDEwMCkKClBEU0lfc3BfNEMgPC0gZGF0YS5mcmFtZShQRFNJX3NwX2RmICU+JSAKICAgICAgICAgICAgICAgICAgICAgICAgICAgZHBseXI6Omdyb3VwX2J5KGNoYW5nZV80QykgJT4lIAogICAgICAgICAgICAgICAgICAgICAgICAgICBkcGx5cjo6c3VtbWFyaXNlKHNwZWNpZXNfbiAgID0gbGVuZ3RoKHNwZWNpZXNfblshaXMubmEoc3BlY2llc19uKV0pLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFxdWF0aWNfbiAgID0gbGVuZ3RoKGFxdWF0aWNfblshaXMubmEoYXF1YXRpY19uKV0pLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFyYm9yZWFsX24gID0gbGVuZ3RoKGFyYm9yZWFsX25bIWlzLm5hKGFyYm9yZWFsX24pXSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9zc29yaWFsX24gPSBsZW5ndGgoZm9zc29yaWFsX25bIWlzLm5hKGZvc3NvcmlhbF9uKV0pLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdyb3VuZF9uICAgID0gbGVuZ3RoKGdyb3VuZF9uWyFpcy5uYShncm91bmRfbildKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZW1pX2FxX24gICA9IGxlbmd0aChzZW1pX2FxX25bIWlzLm5hKHNlbWlfYXFfbildKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJlYW1fbiAgICA9IGxlbmd0aChzdHJlYW1fblshaXMubmEoc3RyZWFtX24pXSkpKSAlPiUKICBkcGx5cjo6bXV0YXRlKGFsbF9mcmVxICAgICAgID0gc3BlY2llc19uIC8gc3VtKHNwZWNpZXNfbikgKiAxMDAsCiAgICAgICAgICAgICAgICBhcXVhdGljX2ZyZXEgICA9IGFxdWF0aWNfbiAvIHN1bShhcXVhdGljX24pICogMTAwLAogICAgICAgICAgICAgICAgYXJib3JlYWxfZnJlcSAgPSBhcmJvcmVhbF9uIC8gc3VtKGFyYm9yZWFsX24pICogMTAwLAogICAgICAgICAgICAgICAgZm9zc29yaWFsX2ZyZXEgPSBmb3Nzb3JpYWxfbiAvIHN1bShmb3Nzb3JpYWxfbikgKiAxMDAsCiAgICAgICAgICAgICAgICBncm91bmRfZnJlcSAgICA9IGdyb3VuZF9uIC8gc3VtKGdyb3VuZF9uKSAqIDEwMCwKICAgICAgICAgICAgICAgIHNlbWlfYXFfZnJlcSAgID0gc2VtaV9hcV9uIC8gc3VtKHNlbWlfYXFfbikgKiAxMDAsCiAgICAgICAgICAgICAgICBzdHJlYW1fZnJlcSAgICA9IHN0cmVhbV9uIC8gc3VtKHN0cmVhbV9uKSAqIDEwMCkKYGBgCgpgYGB7ciBQRFNJIGZyZXF9CiMgQ2FsY3VsYXRlIGZyZXF1ZW5jeSBvZiBtb2RlcmF0ZSB0byBleHRyZW1lIGRyb3VnaHQgKDwtMiBQRFNJKSBwZXIgeWVhci4KCiMgVGVtcG9yYWwgY2hhbmdlIGluIFBEU0kgaW50ZW5zaXR5ClBEU0lfMkNfdGltZV9kZiA8LSByYXN0ZXI6OmFzLmRhdGEuZnJhbWUocmFzdGVyOjpyYXN0ZXJUb1BvaW50cyhQRFNJX3NzcDI0NV9yYXN0KSkKUERTSV80Q190aW1lX2RmIDwtIHJhc3Rlcjo6YXMuZGF0YS5mcmFtZShyYXN0ZXI6OnJhc3RlclRvUG9pbnRzKFBEU0lfc3NwNTg1X3Jhc3QpKQoKIyBDb252ZXJ0IHdpZGUgdG8gbG9uZwpmcmVxXzJDX2RmIDwtIFBEU0lfMkNfdGltZV9kZiAlPiUKICB0aWR5cjo6cGl2b3RfbG9uZ2VyKCFjKCJ4IiwieSIpLCBuYW1lc190byA9ICJkYXRlcyIsIHZhbHVlc190byA9ICJQRFNJIikgJT4lCiAgZGF0YS5mcmFtZSgpICU+JQogIHRpZHlyOjpzZXBhcmF0ZShkYXRlcywgYygieWVhciIsICdtb250aHMnKSkgJT4lCiAgZHBseXI6Om11dGF0ZSh5ZWFyID0gYXMubnVtZXJpYyhzdWJzdHJpbmcoeWVhciwgMikpKSAlPiUKICBkcGx5cjo6ZmlsdGVyKHllYXIgPj0gMTk1MCAmIHllYXIgIT0gMjEwMCkKCmZyZXFfNENfZGYgPC0gUERTSV80Q190aW1lX2RmICU+JQogIHRpZHlyOjpwaXZvdF9sb25nZXIoIWMoIngiLCJ5IiksIG5hbWVzX3RvID0gImRhdGVzIiwgdmFsdWVzX3RvID0gIlBEU0kiKSAlPiUKICBkYXRhLmZyYW1lKCkgJT4lCiAgdGlkeXI6OnNlcGFyYXRlKGRhdGVzLCBjKCJ5ZWFyIiwgJ21vbnRocycpKSAlPiUKICBkcGx5cjo6bXV0YXRlKHllYXIgPSBhcy5udW1lcmljKHN1YnN0cmluZyh5ZWFyLCAyKSkpICU+JQogIGRwbHlyOjpmaWx0ZXIoeWVhciA+PSAxOTUwICYgeWVhciAhPSAyMTAwKQoKIyBTdW1tYXJpc2UgYXZlcmFnZSBtb250aGx5IGNvdW50cyA8LTIgUERTSSBmcm9tIDE5NzAgdG8gMTk5OSBvciAyMDgwIHRvIDIxMDAKZnJlcV9tZWFuX2RmIDwtIGZyZXFfMkNfZGYgJT4lCiAgZHBseXI6OmZpbHRlcih5ZWFyID49IDE5NzAgJiB5ZWFyIDw9IDE5OTkpICU+JQogIGRwbHlyOjpncm91cF9ieSh4LCB5LCB5ZWFyKSAlPiUKICBkcGx5cjo6c3VtbWFyaXNlKGNvdW50ID0gc3VtKFBEU0kgPCAtMikpICU+JQogIGRwbHlyOjpncm91cF9ieSh4LCB5KSAlPiUKICBkcGx5cjo6c3VtbWFyaXNlKG1lYW5fY3VyciA9IG1lYW4oY291bnQpKQogIApmcmVxXzJDX2RpZmZfZGYgPC0gZnJlcV8yQ19kZiAlPiUKICBkcGx5cjo6ZmlsdGVyKHllYXIgPj0gMjA4MCAmIHllYXIgIT0gMjEwMCkgJT4lCiAgZHBseXI6Omdyb3VwX2J5KHgsIHksIHllYXIpICU+JQogIGRwbHlyOjpzdW1tYXJpc2UoY291bnQgPSBzdW0oUERTSSA8IC0yKSkgJT4lIAogIGRwbHlyOjpncm91cF9ieSh4LCB5KSAlPiUKICBkcGx5cjo6c3VtbWFyaXNlKG1lYW5fMkMgPSBtZWFuKGNvdW50KSkgJT4lIAogIGRwbHlyOjppbm5lcl9qb2luKGZyZXFfbWVhbl9kZiwgYnkgPSBjKCJ4IiA9ICJ4IiwgInkiID0gInkiKSkgJT4lCiAgZHBseXI6Om11dGF0ZShkaWZmXzJDID0gbWVhbl8yQyAtIG1lYW5fY3VycikKCmZyZXFfNENfZGlmZl9kZiA8LSBmcmVxXzRDX2RmICU+JQogIGRwbHlyOjpmaWx0ZXIoeWVhciA+PSAyMDgwICYgeWVhciAhPSAyMTAwKSAlPiUKICBkcGx5cjo6Z3JvdXBfYnkoeCwgeSwgeWVhcikgJT4lCiAgZHBseXI6OnN1bW1hcmlzZShjb3VudCA9IHN1bShQRFNJIDwgLTIpKSAlPiUgCiAgZHBseXI6Omdyb3VwX2J5KHgsIHkpICU+JQogIGRwbHlyOjpzdW1tYXJpc2UobWVhbl80QyA9IG1lYW4oY291bnQpKSAlPiUgCiAgZHBseXI6OmlubmVyX2pvaW4oZnJlcV8yQ19kaWZmX2RmLCBieSA9IGMoIngiID0gIngiLCAieSIgPSAieSIpKSAlPiUKICBkcGx5cjo6bXV0YXRlKGRpZmZfNEMgPSBtZWFuXzRDIC0gbWVhbl9jdXJyKQpgYGAKCmBgYHtyIFBEU0kgZHVyfQojIENhbGN1bGF0ZSBkdXJhdGlvbiBvZiBtb2RlcmF0ZSB0byBleHRyZW1lIGRyb3VnaHQgKDwtMiBQRFNJKSBmcm9tIDE5NzAgdG8gMTk5OQpkdXJfY3Vycl9kZiA8LSBmcmVxXzJDX2RmICU+JQogIGRwbHlyOjptdXRhdGUoYmluID0gaWZlbHNlKFBEU0kgPCAtMiwgMSwgMCkpICU+JQogIGRwbHlyOjpmaWx0ZXIoeWVhciA+PSAxOTcwICYgeWVhciA8PSAxOTk5KSAlPiUKICBkcGx5cjo6Z3JvdXBfYnkoeCwgeSkgJT4lIAogIGRwbHlyOjpzdW1tYXJpc2UobWVhbl9jdXJyID0gbWVhbihybGUoYmluKSRsZW5ndGhzW3JsZShiaW4pJHZhbHVlcz09MV0pKSAlPiUKICByZXBsYWNlKGlzLm5hKC4pLCAwKQoKIyBDYWxjdWxhdGUgZHVyYXRpb24gb2YgbW9kZXJhdGUgdG8gZXh0cmVtZSBkcm91Z2h0ICg8LTIgUERTSSkgZnJvbSAyMDgwIHRvIDIxMDAKZHVyXzJDX2RmIDwtIGZyZXFfMkNfZGYgJT4lCiAgZHBseXI6Om11dGF0ZShiaW4gPSBpZmVsc2UoUERTSSA8IC0yLCAxLCAwKSkgJT4lIAogIGRwbHlyOjpmaWx0ZXIoeWVhciA+PSAyMDgwICYgeWVhciAhPSAyMTAwKSAlPiUKICBkcGx5cjo6Z3JvdXBfYnkoeCwgeSkgJT4lIAogIGRwbHlyOjpzdW1tYXJpc2UobWVhbl8yQyA9IG1lYW4ocmxlKGJpbikkbGVuZ3Roc1tybGUoYmluKSR2YWx1ZXM9PTFdKSkgJT4lCiAgcmVwbGFjZShpcy5uYSguKSwgMCkgJT4lCiAgZHBseXI6OmlubmVyX2pvaW4oZHVyX2N1cnJfZGYsIGJ5ID0gYygieCIgPSAieCIsICJ5IiA9ICJ5IikpICU+JQogIGRwbHlyOjptdXRhdGUoZGlmZl8yQyA9IG1lYW5fMkMgLSBtZWFuX2N1cnIpCgpkdXJfNENfZGYgPC0gZnJlcV80Q19kZiAlPiUgCiAgZHBseXI6Om11dGF0ZShiaW4gPSBpZmVsc2UoUERTSSA8IC0yLCAxLCAwKSkgJT4lCiAgZHBseXI6Omdyb3VwX2J5KHgsIHkpICU+JSAKICBkcGx5cjo6ZmlsdGVyKHllYXIgPj0gMjA4MCAmIHllYXIgIT0gMjEwMCkgJT4lCiAgZHBseXI6OnN1bW1hcmlzZShtZWFuXzRDID0gbWVhbihybGUoYmluKSRsZW5ndGhzW3JsZShiaW4pJHZhbHVlcz09MV0pKSAlPiUKICByZXBsYWNlKGlzLm5hKC4pLCAwKSAlPiUKICBkcGx5cjo6aW5uZXJfam9pbihkdXJfMkNfZGYsIGJ5ID0gYygieCIgPSAieCIsICJ5IiA9ICJ5IikpICU+JQogIGRwbHlyOjptdXRhdGUoZGlmZl80QyA9IG1lYW5fNEMgLSBtZWFuX2N1cnIpCmBgYAoKVGhlIHNpbXVsdGFuZW91cyByaXNrIG9mIGRyb3VnaHQgaW50ZW5zaXR5LCBmcmVxdWVuY3ksIGFuZCBkdXJhdGlvbiB3aXRoaW4gYSBncmlkIGNlbGwgdGhhdCBhcmUgb2NjdXBpZWQgYnkgYW51cmFucyB3YXMgY2FsY3VsYXRlZCBieSBjb252ZXJ0aW5nIGVhY2ggcmlzayBjYXRlZ29yeSBhcyBiaW5hcnkuIEdpcmQgY2VsbHMgd2l0aCBhIM6UUERTSVtpbnRlbnNpdHldIGJlbG93IC0xIChpbmRpY2F0aW5nIGEgZGVjcmVhc2UgaW4gUERTSSkgd2VyZSBhc3NpZ25lZCBhIOKAmDHigJkgYmluYXJ5LiBCb3RoIM6UUERTSVtmcmVxdWVuY3ldIGFuZCDOlFBEU0lbZHVyYXRpb25dIHdlcmUgYXNzaWduZWQgYSBiaW5hcnkgb2Yg4oCYMeKAmSBpZiB0aGUgZ3JpZCBjZWxsIGhhcyBhIHZhbHVlIG9mIDEgbW9udGggb3IgaGlnaGVyIChpbmRpY2F0aW5nIGluY3JlYXNlIGluIGZyZXF1ZW5jeSBvciBkdXJhdGlvbiByZWxhdGl2ZSB0byBjdXJyZW50IHNjZW5hcmlvKS4gVGhlIG51bWJlciBvZiBvdmVybGFwcGluZyBiaW5hcmllcyB3ZXJlIHN1bW1lZCB1cCBwZXIgZ3JpZCBjZWxsLiBUaGVyZWZvcmUsIGEgcmlzayBmYWN0b3Igb2YgMiBpbmRpY2F0ZSBhbnVyYW5zIGluIHRoZSBhc3NpZ25lZCBncmlkIGNlbGwgYXJlIGF0IGluY3JlYXNpbmcgcmlzayBvZiB0d28gZHJvdWdodCBldmVudHMuIFdlIGVzdGltYXRlZCB3aGljaCBzcGVjaWVzIGFzc2VtYmxhZ2VzIHdlcmUgcmlzayB0byBkcm91Z2h0IHVzaW5nIGFuIGFyYml0cmFyeSByaXNrIGZhY3RvciAoc3BlY2llcyByaWNobmVzcyDDlyBkcm91Z2h0IHJpc2spLCB3aGVyZSBncmlkIGNlbGxzIHdpdGggaGlnaCBkcm91Z2h0IHJpc2sgYW5kIGhpZ2ggc3BlY2llcyByaWNobmVzcyBoYXZlIGhpZ2hlciBzcGVjaWVzLWFzc2VtYmxhZ2UgcmlzayB0aGFuIGdpcmQgY2VsbHMgd2l0aCBoaWdoIGRyb3VnaHQgcmlzayBhbmQgbG93IHNwZWNpZXMgcmljaG5lc3MgKGxvdyBzcGVjaWVzLWFzc2VtYmxhZ2UgcmlzaykuCgpgYGB7ciBQRFNJIGNvbWJ9CiMgSW50ZW5zaXR5Cm5hbWVzKFBEU0lfMkNfZGlmZl9yYXN0KSA8LSAiZGVsdGFfaW50XzJDIgpuYW1lcyhQRFNJXzRDX2RpZmZfcmFzdCkgPC0gImRlbHRhX2ludF80QyIKCiMgRnJlcXVlbmN5CmZyZXFfZGlmZl9yYXN0IDwtIHJhc3RlckZyb21YWVooZnJlcV80Q19kaWZmX2RmKSAjIGNvbnZlcnQgdG8gcmFzdGVyCmNycyhmcmVxX2RpZmZfcmFzdCkgPC0gIitwcm9qPWxvbmdsYXQgK2RhdHVtPVdHUzg0ICtub19kZWZzICtlbGxwcz1XR1M4NCArdG93Z3M4ND0wLDAsMCIKZnJlcV9kaWZmX3Jhc3QgPC0gcHJvamVjdFJhc3RlcihmcmVxX2RpZmZfcmFzdCwgYW51cmFuX3NyKSAjIG1hdGNoIGFudXJhbiBleHRlbnQKZnJlcV9kaWZmX2RmICAgPC0gcmFzdGVyOjphcy5kYXRhLmZyYW1lKHJhc3Rlcjo6cmFzdGVyVG9Qb2ludHMoZnJlcV9kaWZmX3Jhc3QpKQoKUERTSV9mcmVxX2RpZmYgPC0gc3Vic2V0KGZyZXFfZGlmZl9yYXN0LCA0OjUpCm5hbWVzKFBEU0lfZnJlcV9kaWZmKSA8LSBjKCJkZWx0YV9mcmVxXzJDIiwgImRlbHRhX2ZyZXFfNEMiKQoKIyBEdXJhdGlvbgpkdXJfZGlmZl9yYXN0IDwtIHJhc3Rlcjo6cmFzdGVyRnJvbVhZWihkdXJfNENfZGYpICMgY29udmVydCB0byByYXN0ZXIKY3JzKGR1cl9kaWZmX3Jhc3QpIDwtICIrcHJvaj1sb25nbGF0ICtkYXR1bT1XR1M4NCArbm9fZGVmcyArZWxscHM9V0dTODQgK3Rvd2dzODQ9MCwwLDAiCmR1cl9kaWZmX3Jhc3QgPC0gcmFzdGVyOjpwcm9qZWN0UmFzdGVyKGR1cl9kaWZmX3Jhc3QsIGFudXJhbl9zcikgIyBtYXRjaCBhbnVyYW4gZXh0ZW50CmR1cl9kaWZmX2RmIDwtIHJhc3Rlcjo6YXMuZGF0YS5mcmFtZShyYXN0ZXI6OnJhc3RlclRvUG9pbnRzKGR1cl9kaWZmX3Jhc3QpKQoKUERTSV9kdXJfZGlmZiAgPC0gc3Vic2V0KGR1cl9kaWZmX3Jhc3QsIDQ6NSkKbmFtZXMoUERTSV9kdXJfZGlmZikgPC0gYygiZGVsdGFfZHVyXzJDIiwgImRlbHRhX2R1cl80QyIpCgojIENvbWJpbmUgcmVsYXRpdmUgUERTSSBtZXRyaWNzClBEU0lfcmlza19jb21iX3Jhc3QgPC0gcmFzdGVyOjpzdGFjayhQRFNJXzJDX2RpZmZfcmFzdCwgUERTSV80Q19kaWZmX3Jhc3QsIFBEU0lfZnJlcV9kaWZmLCBQRFNJX2R1cl9kaWZmLCByZXNhbXBsZShhbnVyYW5fc3IsIFBEU0lfNENfZGlmZl9yYXN0KSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKUERTSV9yaXNrX2NvbWJfZGYgPC0gcmFzdGVyOjphcy5kYXRhLmZyYW1lKHJhc3Rlcjo6cmFzdGVyVG9Qb2ludHMoUERTSV9yaXNrX2NvbWJfcmFzdCkpICU+JQogIGRwbHlyOjpyZW5hbWUoInNwX24iID0gbGF5ZXIpICU+JQogIGRwbHlyOjpmaWx0ZXIoIWlzLm5hKHNwX24pKSAlPiUKICBkcGx5cjo6bXV0YXRlKGRlbHRhX2ludF8yQ19iaW4gPSBpZmVsc2UoZGVsdGFfaW50XzJDIDwgLTEsIDEsIDApLCAjIGRlbHRhX1BEU0kgPCAtMQogICAgICAgICBkZWx0YV9pbnRfNENfYmluID0gaWZlbHNlKGRlbHRhX2ludF80QyA8IC0xLCAxLCAwKSwgIyBkZWx0YV9QRFNJIDwgLTEKICAgICAgICAgZGVsdGFfZnJlcV8yQ19iaW4gPSBpZmVsc2UoZGVsdGFfZnJlcV8yQyA+MSwgMSwgMCksICMgbW9udGggPiAxCiAgICAgICAgIGRlbHRhX2ZyZXFfNENfYmluID0gaWZlbHNlKGRlbHRhX2ZyZXFfNEMgPjEsIDEsIDApLCAjIG1vbnRoID4gMQogICAgICAgICBkZWx0YV9kdXJfMkNfYmluID0gaWZlbHNlKGRlbHRhX2R1cl8yQyA+MSwgMSwgMCksICMgbW9udGggPiAxCiAgICAgICAgIGRlbHRhX2R1cl80Q19iaW4gPSBpZmVsc2UoZGVsdGFfZHVyXzRDID4xLCAxLCAwKSkgJT4lICMgbW9udGggPiAxIAogIGRwbHlyOjpyb3d3aXNlKCkgJT4lCiAgZHBseXI6Om11dGF0ZShjb3VudF8yQyA9IHN1bShkZWx0YV9pbnRfMkNfYmluLCBkZWx0YV9mcmVxXzJDX2JpbiwgZGVsdGFfZHVyXzJDX2JpbiwgbmEucm0gPSBUKSwKICAgICAgICAgCiAgICAgICAgIGNvdW50XzRDID0gc3VtKGRlbHRhX2ludF80Q19iaW4sIGRlbHRhX2ZyZXFfNENfYmluLCBkZWx0YV9kdXJfNENfYmluLCBuYS5ybSA9IFQpLAogICAgICAgICByaXNrXzJDICA9IHNwX24gKiBjb3VudF8yQywKICAgICAgICAgcmlza180QyAgPSBzcF9uICogY291bnRfNEMsCiAgICAgICAgIGNvdW50XzJDID0gZmFjdG9yKGNvdW50XzJDLCBsZXZlbHMgPSBjKCIzIiwgIjIiLCAiMSIpKSwKICAgICAgICAgY291bnRfNEMgPSBmYWN0b3IoY291bnRfNEMsIGxldmVscyA9IGMoIjMiLCAiMiIsICIxIikpCiAgICAgICAgICkKYGBgCgpgYGB7ciBGaWcgUzIsIG1lc3NhZ2U9RkFMU0UsIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLmhlaWdodD02LjUsIGZpZy53aWR0aD05fQojIENvbWJpbmUgYWJzb2x1dGUgUERTSSBtZXRyaWNzClBEU0lfYWJfcmFzdCA8LSByYXN0ZXI6OnN0YWNrKFBEU0lfY3VyX21lYW5fcmFzdCwgUERTSV8yQ19tZWFuX3Jhc3QsIFBEU0lfNENfbWVhbl9yYXN0LCBmcmVxX2RpZmZfcmFzdCwgZHVyX2RpZmZfcmFzdCwgcmVzYW1wbGUoYW51cmFuX3NyLCBQRFNJXzRDX21lYW5fcmFzdCkpIApQRFNJX2FiX3Jhc3RfY3JvcCA8LSByYXN0ZXI6Om1hc2soY3JvcChQRFNJX2FiX3Jhc3QsIGV4dGVudCh3b3JsZCkpLCB3b3JsZCkgIyBjcm9wIAoKUERTSV9hYl9kZiA8LSByYXN0ZXI6OmFzLmRhdGEuZnJhbWUocmFzdGVyOjpyYXN0ZXJUb1BvaW50cyhQRFNJX2FiX3Jhc3RfY3JvcCkpICU+JQogIGRwbHlyOjpyZW5hbWUoUERTSV9jdXIgPSAibGF5ZXIuMSIsCiAgICAgICAgICAgICAgICBQRFNJXzJDICA9ICJsYXllci4yIiwKICAgICAgICAgICAgICAgIFBEU0lfNEMgID0gImxheWVyLjMiLAogICAgICAgICAgICAgICAgZnJlcV9jdXIgPSAibWVhbl9jdXJyLjEiLAogICAgICAgICAgICAgICAgZnJlcV8yQyAgPSAibWVhbl8yQy4xIiwKICAgICAgICAgICAgICAgIGZyZXFfNEMgID0gIm1lYW5fNEMuMSIsCiAgICAgICAgICAgICAgICBkdXJfY3VyICA9ICJtZWFuX2N1cnIuMiIsCiAgICAgICAgICAgICAgICBkdXJfMkMgICA9ICJtZWFuXzJDLjIiLAogICAgICAgICAgICAgICAgZHVyXzRDICAgPSAibWVhbl80Qy4yIiwKICAgICAgICAgICAgICAgIHNwX24gICAgID0gImxheWVyLjQiKSAlPiUKICBmaWx0ZXIoc3BfbiAhPSAiTkEiKQoKY29sb3Vyc19QRFNJIDwtIFJDb2xvckJyZXdlcjo6YnJld2VyLnBhbCg5LCAiUmRCdSIpCgojIEludGVuc2l0eQpQRFNJX2N1cl9wbG90IDwtIFBEU0lfYWJfZGYgJT4lCiAgZHBseXI6Om11dGF0ZShQRFNJX2N1cl9jYXQgPSBjYXNlX3doZW4oCiAgICBQRFNJX2N1ciA+PSAyICYgUERTSV9jdXIgPCAzIH4gJzInLCAgCiAgICBQRFNJX2N1ciA+PSAxICYgUERTSV9jdXIgPCAyIH4gJzEnLCAgCiAgICBQRFNJX2N1ciA+PSAtMSAmIFBEU0lfY3VyIDwgMSB+ICcwJwogICkpICU+JSAKICBkcGx5cjo6bXV0YXRlKFBEU0lfY3VyX2NhdCA9IGZhY3RvcihQRFNJX2N1cl9jYXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV2ZWxzID0gYygnMCcsICcxJywgJzInKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcmRlcmVkID0gVFJVRSkpICU+JQogIGZpbHRlcihQRFNJX2N1cl9jYXQgIT0gIk5BIikgJT4lCiAgZ2dwbG90KCkgKwogIGdlb21fcmFzdGVyKGFlcyh5ID0geSwgeCA9IHgsIGZpbGwgPSBQRFNJX2N1cl9jYXQpKSArCiAgZ2VvbV9wb2x5Z29uKGRhdGEgPSB3b3JsZF9zcGRmLCBhZXMoeCA9IGxvbmcsIHkgPSBsYXQsIGdyb3VwID0gZ3JvdXApLCBjb2xvdXIgPSAiIzY0Njg2YiIsIGZpbGwgPSBOQSwgc2l6ZSA9IDAuMSkgKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGMoIiNGN0Y3RjciLCAiI0QxRTVGMCIgLCIjOTJDNURFIikpICsKICB0aGVtZV92b2lkKCkgKyB5bGFiKE5VTEwpICsgeGxhYihOVUxMKSArCiAgZ2d0aXRsZSgiTWVhbiBQRFNJIGludGVuc2l0eSAoMTk3MOKAkzIwMDApIikgKwogIHNjYWxlX3lfY29udGludW91cyhsaW1pdHMgPSBjKC02MCwgOTApLCBleHBhbmQgPSBjKDAsIDApKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGxpbWl0cyA9IGMoLTE4MCwgMTgwKSwgZXhwYW5kID0gYygwLCAwKSkgKwogIHRoZW1lKGF4aXMudGl0bGUgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50ZXh0ID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIGF4aXMudGlja3MgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApKSArCiAgY29vcmRfZml4ZWQocmF0aW8gPSAxKSAjIGZpeGVkIHJhdGlvCgpQRFNJXzJDX3Bsb3QgPC0gUERTSV9hYl9kZiAlPiUKICBkcGx5cjo6bXV0YXRlKFBEU0lfMkNfY2F0ID0gY2FzZV93aGVuKAogICAgUERTSV8yQyA+PSA0IH4gIjQiLCAKICAgIFBEU0lfMkMgPj0gMyAmIFBEU0lfMkMgPCA0IH4gJzMnLAogICAgUERTSV8yQyA+PSAyICYgUERTSV8yQyA8IDMgfiAnMicsICAKICAgIFBEU0lfMkMgPj0gMSAmIFBEU0lfMkMgPCAyIH4gJzEnLCAgCiAgICBQRFNJXzJDID49IC0xICYgUERTSV8yQyA8IDEgfiAnMCcsCiAgICBQRFNJXzJDID49IC0yICYgUERTSV8yQyA8IC0xIH4gJy0xJywKICAgIFBEU0lfMkMgPj0gLTMgJiBQRFNJXzJDIDwgLTIgfiAnLTInLAogICAgUERTSV8yQyA+PSAtNCAmIFBEU0lfMkMgPCAtMyB+ICctMycsICAgCiAgICBQRFNJXzJDIDwgLTQgfiAnLTQnIAogICkpICU+JSAKICBkcGx5cjo6bXV0YXRlKFBEU0lfMkNfY2F0ID0gZmFjdG9yKFBEU0lfMkNfY2F0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldmVscyA9IGMoJy00JywgJy0zJywgJy0yJywgJy0xJywgJzAnLCAnMScsICcyJywgJzMnLCAnNCcpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9yZGVyZWQgPSBUUlVFKSkgJT4lCiAgZmlsdGVyKFBEU0lfMkNfY2F0ICE9ICJOQSIpICU+JQogIGdncGxvdCgpICsKICBnZW9tX3Jhc3RlcihhZXMoeSA9IHksIHggPSB4LCBmaWxsID0gUERTSV8yQ19jYXQpKSArCiAgZ2VvbV9wb2x5Z29uKGRhdGEgPSB3b3JsZF9zcGRmLCBhZXMoeCA9IGxvbmcsIHkgPSBsYXQsIGdyb3VwID0gZ3JvdXApLCBjb2xvdXIgPSAiIzY0Njg2YiIsIGZpbGwgPSBOQSwgc2l6ZSA9IDAuMSkgKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGNvbG91cnNfUERTSSkgKwogIHRoZW1lX3ZvaWQoKSArIHlsYWIoTlVMTCkgKyB4bGFiKE5VTEwpICsKICBnZ3RpdGxlKCJNZWFuIFBEU0kgaW50ZW5zaXR5ICgrMsKwQykiKSArCiAgc2NhbGVfeV9jb250aW51b3VzKGxpbWl0cyA9IGMoLTYwLCA5MCksIGV4cGFuZCA9IGMoMCwgMCkpICsKICBzY2FsZV94X2NvbnRpbnVvdXMobGltaXRzID0gYygtMTgwLCAxODApLCBleHBhbmQgPSBjKDAsIDApKSArCiAgdGhlbWUoYXhpcy50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRleHQgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50aWNrcyA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCkpICsKICBjb29yZF9maXhlZChyYXRpbyA9IDEpICMgZml4ZWQgcmF0aW8KClBEU0lfNENfcGxvdCA8LSBQRFNJX2FiX2RmICU+JQogIGRwbHlyOjptdXRhdGUoUERTSV80Q19jYXQgPSBjYXNlX3doZW4oCiAgICBQRFNJXzRDID49IDQgfiAiNCIsIAogICAgUERTSV80QyA+PSAzICYgUERTSV80QyA8IDQgfiAnMycsCiAgICBQRFNJXzRDID49IDIgJiBQRFNJXzRDIDwgMyB+ICcyJywgIAogICAgUERTSV80QyA+PSAxICYgUERTSV80QyA8IDIgfiAnMScsICAKICAgIFBEU0lfNEMgPj0gLTEgJiBQRFNJXzRDIDwgMSB+ICcwJywKICAgIFBEU0lfNEMgPj0gLTIgJiBQRFNJXzRDIDwgLTEgfiAnLTEnLAogICAgUERTSV80QyA+PSAtMyAmIFBEU0lfNEMgPCAtMiB+ICctMicsCiAgICBQRFNJXzRDID49IC00ICYgUERTSV80QyA8IC0zIH4gJy0zJywgICAKICAgIFBEU0lfNEMgPCAtNCB+ICctNCcgCiAgKSkgJT4lIAogIGRwbHlyOjptdXRhdGUoUERTSV80Q19jYXQgPSBmYWN0b3IoUERTSV80Q19jYXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV2ZWxzID0gYygnLTQnLCAnLTMnLCAnLTInLCAnLTEnLCAnMCcsICcxJywgJzInLCAnMycsICc0JyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3JkZXJlZCA9IFRSVUUpKSAlPiUKICBmaWx0ZXIoUERTSV80Q19jYXQgIT0gIk5BIikgJT4lCiAgZ2dwbG90KCkgKwogIGdlb21fcmFzdGVyKGFlcyh5ID0geSwgeCA9IHgsIGZpbGwgPSBQRFNJXzRDX2NhdCkpICsKICBnZW9tX3BvbHlnb24oZGF0YSA9IHdvcmxkX3NwZGYsIGFlcyh4ID0gbG9uZywgeSA9IGxhdCwgZ3JvdXAgPSBncm91cCksIGNvbG91ciA9ICIjNjQ2ODZiIiwgZmlsbCA9IE5BLCBzaXplID0gMC4xKSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gY29sb3Vyc19QRFNJLCBuYW1lID0gIlBEU0kiLCBndWlkZSA9IGd1aWRlX2xlZ2VuZChyZXZlcnNlID0gVFJVRSwgbnJvdyA9IDEpKSArCiAgdGhlbWVfdm9pZCgpICsgeWxhYihOVUxMKSArIHhsYWIoTlVMTCkgKwogIGdndGl0bGUoIk1lYW4gUERTSSBpbnRlbnNpdHkgKCs0wrBDKSIpICsKICBzY2FsZV95X2NvbnRpbnVvdXMobGltaXRzID0gYygtNjAsIDkwKSwgZXhwYW5kID0gYygwLCAwKSkgKwogIHNjYWxlX3hfY29udGludW91cyhsaW1pdHMgPSBjKC0xODAsIDE4MCksIGV4cGFuZCA9IGMoMCwgMCkpICsKICB0aGVtZShheGlzLnRpdGxlID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIGF4aXMudGV4dCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRpY2tzID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSwKICAgICAgICBsZWdlbmQudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgpLCAKICAgICAgICBsZWdlbmQua2V5LmhlaWdodD0gdW5pdCgwLjIsICdjbScpLAogICAgICAgIGxlZ2VuZC5rZXkud2lkdGg9IHVuaXQoMC4yLCAnY20nKSwKICAgICAgICBsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIikgKwogIGNvb3JkX2ZpeGVkKHJhdGlvID0gMSkgIyBmaXhlZCByYXRpbwoKaW50X2xlZ2VuZCA8LSBjb3dwbG90OjpnZXRfbGVnZW5kKFBEU0lfNENfcGxvdCkKCmludF9wcm93IDwtIGNvd3Bsb3Q6OnBsb3RfZ3JpZChQRFNJX2N1cl9wbG90ICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKSwgCiAgICAgICAgICAgICAgICAgICBQRFNJXzJDX3Bsb3QgKyAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKSwgCiAgICAgICAgICAgICAgICAgICBQRFNJXzRDX3Bsb3QgKyB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpLCAKICAgICAgICAgICAgICAgICAgIGFsaWduID0gInYiLCBuY29sID0gMywgbGFiZWxzID0gYygnYScsICdiJywgJ2MnKSkgCgppbnRfcGxvdHMgPC0gY293cGxvdDo6cGxvdF9ncmlkKGludF9wcm93LCBpbnRfbGVnZW5kLCBuY29sID0gMSwgcmVsX2hlaWdodHMgPSBjKDEsIC4xKSkKCiMgRnJlcXVlbmN5CmZyZXFfY3VyX3Bsb3QgPC0gUERTSV9hYl9kZiAlPiUKICBkcGx5cjo6bXV0YXRlKGZyZXFfY3VyX2NhdCA9IGNhc2Vfd2hlbigKICAgIGZyZXFfY3VyID4gMC4xICYgZnJlcV9jdXIgPCAxIH4gJzwxJwogICkpICU+JQogIGZpbHRlcihmcmVxX2N1cl9jYXQgIT0gIk5BIikgJT4lCiAgZ2dwbG90KCkgKwogIGdlb21fcmFzdGVyKGFlcyh5ID0geSwgeCA9IHgsIGZpbGwgPSBmcmVxX2N1cl9jYXQpKSArCiAgZ2VvbV9wb2x5Z29uKGRhdGEgPSB3b3JsZF9zcGRmLCBhZXMoeCA9IGxvbmcsIHkgPSBsYXQsIGdyb3VwID0gZ3JvdXApLCBjb2xvdXIgPSAiIzY0Njg2YiIsIGZpbGwgPSBOQSwgc2l6ZSA9IDAuMSkgKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9ICIjZWRlZGVkIikgKwogIHRoZW1lX3ZvaWQoKSArIHlsYWIoTlVMTCkgKyB4bGFiKE5VTEwpICsKICBnZ3RpdGxlKCJNZWFuIGRyb3VnaHQgZnJlcXVlbmN5ICgxOTcw4oCTMjAwMCkiKSArCiAgc2NhbGVfeV9jb250aW51b3VzKGxpbWl0cyA9IGMoLTYwLCA5MCksIGV4cGFuZCA9IGMoMCwgMCkpICsKICBzY2FsZV94X2NvbnRpbnVvdXMobGltaXRzID0gYygtMTgwLCAxODApLCBleHBhbmQgPSBjKDAsIDApKSArCiAgdGhlbWUoYXhpcy50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRleHQgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50aWNrcyA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCkpICsKICBjb29yZF9maXhlZChyYXRpbyA9IDEpICMgZml4ZWQgcmF0aW8KCmZyZXFfMkNfcGxvdCA8LSBQRFNJX2FiX2RmICU+JQogIGRwbHlyOjptdXRhdGUoZnJlcV8yQ19jYXQgPSBjYXNlX3doZW4oCiAgICBmcmVxXzJDID49IDEwIH4gIjEwLTEyIiwgCiAgICBmcmVxXzJDID49IDggJiBmcmVxXzJDIDwgMTAgfiAnOC0xMCcsCiAgICBmcmVxXzJDID49IDYgJiBmcmVxXzJDIDwgOCB+ICc2LTgnLCAgCiAgICBmcmVxXzJDID49IDQgJiBmcmVxXzJDIDwgNiB+ICc0LTYnLCAgCiAgICBmcmVxXzJDID49IDIgJiBmcmVxXzJDIDwgNCB+ICcyLTQnLAogICAgZnJlcV8yQyA+PSAxICYgZnJlcV8yQyA8IDIgfiAnMS0yJywKICAgIGZyZXFfMkMgPiAwLjEgJiBmcmVxXzJDIDwgMSB+ICc8MScKICApKSAlPiUgCiAgZHBseXI6Om11dGF0ZShmcmVxXzJDX2NhdCA9IGZhY3RvcihmcmVxXzJDX2NhdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldmVscyA9IGMoJzEwLTEyJywgJzgtMTAnLCAnNi04JywgJzQtNicsICcyLTQnLCAnMS0yJywgJzwxJyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcmRlcmVkID0gVFJVRSkpICU+JQogIGZpbHRlcihmcmVxXzJDX2NhdCAhPSAiTkEiKSAlPiUKICBnZ3Bsb3QoKSArCiAgZ2VvbV9yYXN0ZXIoYWVzKHkgPSB5LCB4ID0geCwgZmlsbCA9IGZyZXFfMkNfY2F0KSkgKwogIGdlb21fcG9seWdvbihkYXRhID0gd29ybGRfc3BkZiwgYWVzKHggPSBsb25nLCB5ID0gbGF0LCBncm91cCA9IGdyb3VwKSwgY29sb3VyID0gIiM2NDY4NmIiLCBmaWxsID0gTkEsIHNpemUgPSAwLjEpICsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjKCIjNjcwMDFGIiwgIiNCMjE4MkIiLCAiI0Q2NjA0RCIsICIjRjRBNTgyIiwgIiNGRERCQzciLCAiI0ZBRTlERiIsICIjRjdGN0Y3IikpICsKICB0aGVtZV92b2lkKCkgKyB5bGFiKE5VTEwpICsgeGxhYihOVUxMKSArCiAgZ2d0aXRsZSgiTWVhbiBkcm91Z2h0IGZyZXF1ZW5jeSAoKzLCsEMpIikgKwogIHNjYWxlX3lfY29udGludW91cyhsaW1pdHMgPSBjKC02MCwgOTApLCBleHBhbmQgPSBjKDAsIDApKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGxpbWl0cyA9IGMoLTE4MCwgMTgwKSwgZXhwYW5kID0gYygwLCAwKSkgKwogIHRoZW1lKGF4aXMudGl0bGUgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50ZXh0ID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIGF4aXMudGlja3MgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApKSArCiAgY29vcmRfZml4ZWQocmF0aW8gPSAxKSAjIGZpeGVkIHJhdGlvCgpmcmVxXzRDX3Bsb3QgPC0gUERTSV9hYl9kZiAlPiUKICBkcGx5cjo6bXV0YXRlKGZyZXFfNENfY2F0ID0gY2FzZV93aGVuKAogICAgZnJlcV80QyA+PSAxMCB+ICIxMC0xMiIsIAogICAgZnJlcV80QyA+PSA4ICYgZnJlcV80QyA8IDEwIH4gJzgtMTAnLAogICAgZnJlcV80QyA+PSA2ICYgZnJlcV80QyA8IDggfiAnNi04JywgIAogICAgZnJlcV80QyA+PSA0ICYgZnJlcV80QyA8IDYgfiAnNC02JywgIAogICAgZnJlcV80QyA+PSAyICYgZnJlcV80QyA8IDQgfiAnMi00JywKICAgIGZyZXFfNEMgPj0gMSAmIGZyZXFfNEMgPCAyIH4gJzEtMicsCiAgICBmcmVxXzRDID4gMC4xICYgZnJlcV80QyA8IDEgfiAnPDEnCiAgKSkgJT4lIAogIGRwbHlyOjptdXRhdGUoZnJlcV80Q19jYXQgPSBmYWN0b3IoZnJlcV80Q19jYXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSBjKCcxMC0xMicsICc4LTEwJywgJzYtOCcsICc0LTYnLCAnMi00JywgJzEtMicsICc8MScpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3JkZXJlZCA9IFRSVUUpKSAlPiUKICBmaWx0ZXIoZnJlcV80Q19jYXQgIT0gIk5BIikgJT4lCiAgZ2dwbG90KCkgKwogIGdlb21fcmFzdGVyKGFlcyh5ID0geSwgeCA9IHgsIGZpbGwgPSBmcmVxXzRDX2NhdCkpICsKICBnZW9tX3BvbHlnb24oZGF0YSA9IHdvcmxkX3NwZGYsIGFlcyh4ID0gbG9uZywgeSA9IGxhdCwgZ3JvdXAgPSBncm91cCksIGNvbG91ciA9ICIjNjQ2ODZiIiwgZmlsbCA9IE5BLCBzaXplID0gMC4xKSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYygiIzY3MDAxRiIsICIjQjIxODJCIiwgIiNENjYwNEQiLCAiI0Y0QTU4MiIsICIjRkREQkM3IiwgIiNGQUU5REYiLCAiI0Y3RjdGNyIpLCBuYW1lID0gIk1vbnRocyIsIGd1aWRlID0gZ3VpZGVfbGVnZW5kKHJldmVyc2UgPSBUUlVFLCBucm93ID0gMSkpICsKICB0aGVtZV92b2lkKCkgKyB5bGFiKE5VTEwpICsgeGxhYihOVUxMKSArCiAgZ2d0aXRsZSgiTWVhbiBkcm91Z2h0IGZyZXF1ZW5jeSAoKzTCsEMpIikgKwogIHNjYWxlX3lfY29udGludW91cyhsaW1pdHMgPSBjKC02MCwgOTApLCBleHBhbmQgPSBjKDAsIDApKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGxpbWl0cyA9IGMoLTE4MCwgMTgwKSwgZXhwYW5kID0gYygwLCAwKSkgKwogIHRoZW1lKGF4aXMudGl0bGUgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50ZXh0ID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIGF4aXMudGlja3MgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApLAogICAgICAgIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gOCksIAogICAgICAgIGxlZ2VuZC5rZXkuaGVpZ2h0PSB1bml0KDAuMiwgJ2NtJyksCiAgICAgICAgbGVnZW5kLmtleS53aWR0aD0gdW5pdCgwLjIsICdjbScpLAogICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iKSArCiAgY29vcmRfZml4ZWQocmF0aW8gPSAxKSAjIGZpeGVkIHJhdGlvCgpmcmVxX2xlZ2VuZCA8LSBjb3dwbG90OjpnZXRfbGVnZW5kKGZyZXFfNENfcGxvdCkKCmZyZXFfcHJvdyA8LSBjb3dwbG90OjpwbG90X2dyaWQoZnJlcV9jdXJfcGxvdCArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiksIAogICAgICAgICAgICAgICAgICAgZnJlcV8yQ19wbG90ICsgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiksIAogICAgICAgICAgICAgICAgICAgZnJlcV80Q19wbG90ICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKSwgCiAgICAgICAgICAgICAgICAgICBhbGlnbiA9ICJ2IiwgbmNvbCA9IDMsIGxhYmVscyA9IGMoJ2QnLCAnZScsICdmJykpIAoKZnJlcV9wbG90cyA8LSBjb3dwbG90OjpwbG90X2dyaWQoZnJlcV9wcm93LCBmcmVxX2xlZ2VuZCwgbmNvbCA9IDEsIHJlbF9oZWlnaHRzID0gYygxLCAuMSkpCgoKIyBEdXJhdGlvbgpkdXJfY3VyX3Bsb3QgPC0gUERTSV9hYl9kZiAlPiUKICBkcGx5cjo6bXV0YXRlKGR1cl9jdXJfY2F0ID0gY2FzZV93aGVuKAogICAgZHVyX2N1ciA+PSAyICYgZHVyX2N1ciA8IDQgfiAnMi00JywKICAgICBkdXJfY3VyID49IDEgJiBkdXJfY3VyIDwgMiB+ICcxLTInLAogICAgZHVyX2N1ciA+IDAuMSAmIGR1cl9jdXIgPCAxIH4gJzwxJwogICkpICU+JSAKICBkcGx5cjo6bXV0YXRlKGR1cl9jdXJfY2F0ID0gZmFjdG9yKGR1cl9jdXJfY2F0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldmVscyA9IGMoJzItNCcsICcxLTInLCAnPDEnKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcmRlcmVkID0gVFJVRSkpICU+JQogIGZpbHRlcihkdXJfY3VyX2NhdCAhPSAiTkEiKSAlPiUKICBnZ3Bsb3QoKSArCiAgZ2VvbV9yYXN0ZXIoYWVzKHkgPSB5LCB4ID0geCwgZmlsbCA9IGR1cl9jdXJfY2F0KSkgKwogIGdlb21fcG9seWdvbihkYXRhID0gd29ybGRfc3BkZiwgYWVzKHggPSBsb25nLCB5ID0gbGF0LCBncm91cCA9IGdyb3VwKSwgY29sb3VyID0gIiM2NDY4NmIiLCBmaWxsID0gTkEsIHNpemUgPSAwLjEpICsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjKCIjRkREQkM3IiwgIiNGQUU5REYiLCAiI0Y3RjdGNyIpKSArCiAgdGhlbWVfdm9pZCgpICsgeWxhYihOVUxMKSArIHhsYWIoTlVMTCkgKwogIGdndGl0bGUoIk1lYW4gZHJvdWdodCBkdXJhdGlvbiAoMTk3MOKAkzIwMDApIikgKwogIHNjYWxlX3lfY29udGludW91cyhsaW1pdHMgPSBjKC02MCwgOTApLCBleHBhbmQgPSBjKDAsIDApKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGxpbWl0cyA9IGMoLTE4MCwgMTgwKSwgZXhwYW5kID0gYygwLCAwKSkgKwogIHRoZW1lKGF4aXMudGl0bGUgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50ZXh0ID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIGF4aXMudGlja3MgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApKSArCiAgY29vcmRfZml4ZWQocmF0aW8gPSAxKSAjIGZpeGVkIHJhdGlvCgpkdXJfMkNfcGxvdCA8LSBQRFNJX2FiX2RmICU+JQogIGRwbHlyOjptdXRhdGUoZHVyXzJDX2NhdCA9IGNhc2Vfd2hlbigKICAgIGR1cl8yQyA+PSAxMCB+ICI+MTAiLCAKICAgIGR1cl8yQyA+PSA4ICYgZHVyXzJDIDwgMTAgfiAnOC0xMCcsCiAgICBkdXJfMkMgPj0gNiAmIGR1cl8yQyA8IDggfiAnNi04JywgIAogICAgZHVyXzJDID49IDQgJiBkdXJfMkMgPCA2IH4gJzQtNicsICAKICAgIGR1cl8yQyA+PSAyICYgZHVyXzJDIDwgNCB+ICcyLTQnLAogICAgZHVyXzJDID49IDEgJiBkdXJfMkMgPCAyIH4gJzEtMicsCiAgICBkdXJfMkMgPiAwLjEgJiBkdXJfMkMgPCAxIH4gJzwxJwogICkpICU+JSAKICBkcGx5cjo6bXV0YXRlKGR1cl8yQ19jYXQgPSBmYWN0b3IoZHVyXzJDX2NhdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSBjKCc+MTAnLCAnOC0xMCcsICc2LTgnLCAnNC02JywgJzItNCcsICcxLTInLCAnPDEnKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcmRlcmVkID0gVFJVRSkpJT4lCiAgZmlsdGVyKGR1cl8yQ19jYXQgIT0gIk5BIikgJT4lCiAgZ2dwbG90KCkgKwogIGdlb21fcmFzdGVyKGFlcyh5ID0geSwgeCA9IHgsIGZpbGwgPSBkdXJfMkNfY2F0KSkgKwogIGdlb21fcG9seWdvbihkYXRhID0gd29ybGRfc3BkZiwgYWVzKHggPSBsb25nLCB5ID0gbGF0LCBncm91cCA9IGdyb3VwKSwgY29sb3VyID0gIiM2NDY4NmIiLCBmaWxsID0gTkEsIHNpemUgPSAwLjEpICsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjKCIjNjcwMDFGIiwgIiNCMjE4MkIiLCAiI0Q2NjA0RCIsICIjRjRBNTgyIiwgIiNGRERCQzciLCAiI0ZBRTlERiIsICIjRjdGN0Y3IikpICsKICB0aGVtZV92b2lkKCkgKyB5bGFiKE5VTEwpICsgeGxhYihOVUxMKSArCiAgZ2d0aXRsZSgiTWVhbiBkcm91Z2h0IGR1cmF0aW9uICgrMsKwQykiKSArCiAgc2NhbGVfeV9jb250aW51b3VzKGxpbWl0cyA9IGMoLTYwLCA5MCksIGV4cGFuZCA9IGMoMCwgMCkpICsKICBzY2FsZV94X2NvbnRpbnVvdXMobGltaXRzID0gYygtMTgwLCAxODApLCBleHBhbmQgPSBjKDAsIDApKSArCiAgdGhlbWUoYXhpcy50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRleHQgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50aWNrcyA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCkpICsKICBjb29yZF9maXhlZChyYXRpbyA9IDEpICMgZml4ZWQgcmF0aW8KCmR1cl80Q19wbG90IDwtIFBEU0lfYWJfZGYgJT4lCiAgZHBseXI6Om11dGF0ZShkdXJfNENfY2F0ID0gY2FzZV93aGVuKAogICAgZHVyXzRDID49IDEwIH4gIj4xMCIsIAogICAgZHVyXzRDID49IDggJiBkdXJfNEMgPCAxMCB+ICc4LTEwJywKICAgIGR1cl80QyA+PSA2ICYgZHVyXzRDIDwgOCB+ICc2LTgnLCAgCiAgICBkdXJfNEMgPj0gNCAmIGR1cl80QyA8IDYgfiAnNC02JywgIAogICAgZHVyXzRDID49IDIgJiBkdXJfNEMgPCA0IH4gJzItNCcsCiAgICBkdXJfNEMgPj0gMSAmIGR1cl80QyA8IDQgfiAnMS0yJywKICAgIGR1cl80QyA+IDAuMSAmIGR1cl80QyA8IDEgfiAnPDEnCiAgKSkgJT4lIAogIGRwbHlyOjptdXRhdGUoZHVyXzRDX2NhdCA9IGZhY3RvcihkdXJfNENfY2F0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldmVscyA9IGMoJz4xMCcsICc4LTEwJywgJzYtOCcsICc0LTYnLCAnMi00JywgJzEtMicsICc8MScpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9yZGVyZWQgPSBUUlVFKSkgJT4lCiAgZmlsdGVyKGR1cl80Q19jYXQgIT0gIk5BIikgJT4lCiAgZ2dwbG90KCkgKwogIGdlb21fcmFzdGVyKGFlcyh5ID0geSwgeCA9IHgsIGZpbGwgPSBkdXJfNENfY2F0KSkgKwogIGdlb21fcG9seWdvbihkYXRhID0gd29ybGRfc3BkZiwgYWVzKHggPSBsb25nLCB5ID0gbGF0LCBncm91cCA9IGdyb3VwKSwgY29sb3VyID0gIiM2NDY4NmIiLCBmaWxsID0gTkEsIHNpemUgPSAwLjEpICsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjKCIjNjcwMDFGIiwgIiNCMjE4MkIiLCAiI0Q2NjA0RCIsICIjRjRBNTgyIiwgIiNGRERCQzciLCAiI0ZBRTlERiIsICIjRjdGN0Y3IiksIG5hbWUgPSAiTW9udGhzIiwgZ3VpZGUgPSBndWlkZV9sZWdlbmQocmV2ZXJzZSA9IFRSVUUsIG5yb3cgPSAxKSkgKwogIHRoZW1lX3ZvaWQoKSArIHlsYWIoTlVMTCkgKyB4bGFiKE5VTEwpICsKICBnZ3RpdGxlKCJNZWFuIGRyb3VnaHQgZHVyYXRpb24gKCs0wrBDKSIpICsKICBzY2FsZV95X2NvbnRpbnVvdXMobGltaXRzID0gYygtNjAsIDkwKSwgZXhwYW5kID0gYygwLCAwKSkgKwogIHNjYWxlX3hfY29udGludW91cyhsaW1pdHMgPSBjKC0xODAsIDE4MCksIGV4cGFuZCA9IGMoMCwgMCkpICsKICB0aGVtZShheGlzLnRpdGxlID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIGF4aXMudGV4dCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRpY2tzID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSwKICAgICAgICBsZWdlbmQudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgpLCAKICAgICAgICBsZWdlbmQua2V5LnNpemUgPSB1bml0KDAuMiwgJ2NtJyksCiAgICAgICAgbGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIpICsKICBjb29yZF9maXhlZChyYXRpbyA9IDEpICMgZml4ZWQgcmF0aW8KCmR1cl9sZWdlbmQgPC0gY293cGxvdDo6Z2V0X2xlZ2VuZChkdXJfNENfcGxvdCkKCmR1cl9wcm93IDwtIGNvd3Bsb3Q6OnBsb3RfZ3JpZChkdXJfY3VyX3Bsb3QgKyB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpLCAKICAgICAgICAgICAgICAgICAgIGR1cl8yQ19wbG90ICsgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiksIAogICAgICAgICAgICAgICAgICAgZHVyXzRDX3Bsb3QgKyB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpLCAKICAgICAgICAgICAgICAgICAgIGFsaWduID0gInYiLCBuY29sID0gMywgbGFiZWxzID0gYygnZycsICdoJywgJ2knKSkgCgpkdXJfcGxvdHMgPC0gY293cGxvdDo6cGxvdF9ncmlkKGR1cl9wcm93LCBkdXJfbGVnZW5kLCBuY29sID0gMSwgcmVsX2hlaWdodHMgPSBjKDEsIC4xKSkKCgpjb3dwbG90OjpwbG90X2dyaWQoaW50X3Bsb3RzLCBmcmVxX3Bsb3RzLCBkdXJfcGxvdHMsIG5jb2wgPSAxKQpgYGAKCioqRmlnLiBTMi4qKiBNZWFuIG1vbnRobHkgUGFsbWVyIERyb3VnaHQgU2V2ZXJpdHkgSW5kZXggKFBEU0kpIHNlbGYtY2FsaWJyYXRlZCB3aXRoIFBlbm1hbuKAk01vbnRlaXRoIHBvdGVudGlhbCBldmFwb3RyYW5zcGlyYXRpb24gZnJvbSAoKiphKiopIDE5NzDigJMyMDAwLCBhbmQgZnJvbSAyMDgwLTIxMDAgdW5kZXIgKCoqYioqKSB1bmRlciBhbiBpbnRlcm1lZGlhdGUgZW1pc3Npb24gc2NlbmFyaW8gKFNoYXJlZCBTb2Npb2Vjb25vbWljIFBhdGh3YXlzIDIgLSA0LjU7IFNTUDItNC41KSwgYW5kICgqKmMqKikgdW5kZXIgYSBoaWdoIGVtaXNzaW9uIHNjZW5hcmlvIChTU1A1LTguNSkuIE1lYW4geWVhcmx5IGZyZXF1ZW5jeSBvZiBtb2RlcmF0ZSB0byBleHRyZW1lIGRyb3VnaHQgKFBEU0kgPCAtMikgZnJvbSAoKipkKiopIDE5NzDigJMyMDAwLCBhbmQgZnJvbSAyMDgwLTIxMDAgKCoqZSoqKSB1bmRlciBhbiBpbnRlcm1lZGlhdGUgZW1pc3Npb24gc2NlbmFyaW8gKFNTUDItNC41KSwgYW5kICgqKmYqKikgdW5kZXIgYSBoaWdoIGVtaXNzaW9uIHNjZW5hcmlvIChTU1A1LTguNSkuIE1lYW4gZHVyYXRpb24gb2YgbW9kZXJhdGUgdG8gZXh0cmVtZSBkcm91Z2h0IChQRFNJIDwgLTIpIGZyb20gKCoqZyoqKSAxOTcw4oCTMjAwMCwgYW5kIGZyb20gMjA4MC0yMTAwICgqKmgqKikgdW5kZXIgYW4gaW50ZXJtZWRpYXRlIGVtaXNzaW9uIHNjZW5hcmlvIChTU1AyLTQuNSksIGFuZCAoKippKiopIHVuZGVyIGEgaGlnaCBlbWlzc2lvbiBzY2VuYXJpbyAoU1NQNS04LjUpLgoKIyMgU3VtbWFyeSB7LnRhYnNldCAudGFic2V0LWZhZGUgLnRhYnNldC1waWxscyAtfQoKIyMjIEVjb3R5cGUgQUkgZGlzdHJpYnV0aW9uIHsudGFic2V0IC50YWJzZXQtZmFkZSAudGFic2V0LXBpbGxzIC19IAoKTWVhbiDCsSBzLmQuIGFyaWRpdHkgaW5kZXggb2NjdXBpZWQgYnkgZGlmZmVyZW50IGFudXJhbiBlY290eXBlcy4KCmBgYHtyIGVjb3R5cGUsIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0V9CmFpX3NwX2RmICU+JQogIGRwbHlyOjpmaWx0ZXIoYXJpZGl0eSA8PTMpICU+JQogIGRwbHlyOjpzZWxlY3QoYXJpZGl0eSwgc3BlY2llc19uOnN0cmVhbV9uKSAlPiUKICB0aWR5cjo6cGl2b3RfbG9uZ2VyKCFhcmlkaXR5LCBuYW1lc190byA9ICJlY290eXBlIiwgdmFsdWVzX3RvID0gIm1lYW4iKSAlPiUKICBkcGx5cjo6ZmlsdGVyKGVjb3R5cGUgIT0gInNwZWNpZXNfbiIpICU+JQogIGRyb3BfbmEobWVhbikgJT4lCiAgZHBseXI6Omdyb3VwX2J5KGVjb3R5cGUpICU+JQogIGRwbHlyOjpzdW1tYXJpc2UobWVhbiA9IG1lYW4oYXJpZGl0eSksCiAgICAgICAgICAgICAgICAgICBzZCAgID0gc2QoYXJpZGl0eSkpICU+JQogIGRwbHlyOjptdXRhdGUoZWNvdHlwZSA9IHN1YnN0cihlY290eXBlLDEsbmNoYXIoZWNvdHlwZSktMiksCiAgICAgICAgICAgICAgICBtZWFuICAgID0gZm9ybWF0KHJvdW5kKG1lYW4sIDIpLCBuc21hbGwgPSAyKSwKICAgICAgICAgICAgICAgIHNkICAgICAgPSBmb3JtYXQocm91bmQoc2QsIDIpLCBuc21hbGwgPSAyKSwKICAgICAgICAgICAgICAgIGFyaWRpdHkgPSBwYXN0ZShtZWFuLCBzZCwgc2VwID0gIiDCsSAiKSwKICAgICAgICAgICAgICAgIGVjb3R5cGUgPSBjYXNlX3doZW4oCiAgICBlY290eXBlID09ICJzdHJlYW0iICAgIH4gIlN0cmVhbS1kd2VsbGluZyIsCiAgICBlY290eXBlID09ICJhcmJvcmVhbCIgIH4gIkFyYm9yZWFsIiwKICAgIGVjb3R5cGUgPT0gInNlbWlfYXEiICB+ICJTZW1pLWFxdWF0aWMiLAogICAgZWNvdHlwZSA9PSAiYXF1YXRpYyIgIH4gIkFxdWF0aWMiLAogICAgZWNvdHlwZSA9PSAiZ3JvdW5kIiAgfiAiR3JvdW5kLWR3ZWxsaW5nIiwKICAgIGVjb3R5cGUgPT0gImZvc3NvcmlhbCIgfiAiRm9zc29yaWFsIikpICU+JQogIGRwbHlyOjpzZWxlY3QoZWNvdHlwZSwgYXJpZGl0eSkgJT4lCiAgZHBseXI6OmFycmFuZ2UoZGVzYyhhcmlkaXR5KSkgJT4lCiAga25pdHI6OmthYmxlKGNvbC5uYW1lcyA9IGMoIkVjb3R5cGUiLCAiQUkgKG1lYW4gwrEgcy5kLikiKSkKYGBgCgoKIyMjIDLCsEMgQUkgcmlzayB7LnRhYnNldCAudGFic2V0LWZhZGUgLnRhYnNldC1waWxscyAtfSAKClBlcmNlbnQgY2hhbmdlIGluIGFyaWRpdHkgYnkgMjA4MOKAkzIxMDAgKCsgMsKwQykgcmVsYXRpdmUgdG8gY3VycmVudCBjbGltYXRlICgxOTgx4oCTMjAxMCkgZm9yIGFsbCBhbnVyYW5zIGFuZCBieSBlY290eXBlLgoKYGBge3IgYWkgc3VtIDIsIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0V9CiMgY2FsY3VsYXRlIHJlbGF0aXZlIGNoYW5nZSB3aXRoIGZ1dHVyZSBzY2VuYXJpbwphaV9zcF9zdW0gJT4lCiAgZHBseXI6Om11dGF0ZShhbGxfY2hhbmdlICAgICAgID0gKGFpXzJDX3NwX3N1bSRzcGVjaWVzX24gLSBzcGVjaWVzX24pIC8gc3BlY2llc19uICogMTAwLAogICAgICAgICAgICAgICAgYXF1YXRpY19jaGFuZ2UgICA9IChhaV8yQ19zcF9zdW0kYXF1YXRpY19uIC0gYXF1YXRpY19uKSAvIGFxdWF0aWNfbiAqIDEwMCwKICAgICAgICAgICAgICAgIGFyYm9yZWFsX2NoYW5nZSAgPSAoYWlfMkNfc3Bfc3VtJGFyYm9yZWFsX24gLSBhcmJvcmVhbF9uKSAvIGFyYm9yZWFsX24gKiAxMDAsCiAgICAgICAgICAgICAgICBmb3Nzb3JpYWxfY2hhbmdlID0gKGFpXzJDX3NwX3N1bSRmb3Nzb3JpYWxfbiAtIGZvc3NvcmlhbF9uKSAvIGZvc3NvcmlhbF9uICogMTAwLAogICAgICAgICAgICAgICAgZ3JvdW5kX2NoYW5nZSAgICA9IChhaV8yQ19zcF9zdW0kZ3JvdW5kX24gLSBncm91bmRfbikgLyBncm91bmRfbiAqIDEwMCwKICAgICAgICAgICAgICAgIHNlbWlfYXFfY2hhbmdlICAgPSAoYWlfMkNfc3Bfc3VtJHNlbWlfYXFfbiAtIHNlbWlfYXFfbikgLyBzZW1pX2FxX24gKiAxMDAsCiAgICAgICAgICAgICAgICBzdHJlYW1fY2hhbmdlICAgID0gKGFpXzJDX3NwX3N1bSRzdHJlYW1fbiAtIHN0cmVhbV9uKSAvIHN0cmVhbV9uICogMTAwKSAlPiUKICBkcGx5cjo6c2VsZWN0KGMoY2F0ZWdvcnksIGFsbF9jaGFuZ2U6c3RyZWFtX2NoYW5nZSkpICU+JQogIGtuaXRyOjprYWJsZShjb2wubmFtZXMgPSBjKCJFY290eXBlIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkFsbCAoJSkiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICJBcXVhdGljIDLCsEMgKCUpIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkFyYm9yZWFsIDLCsEMgKCUpIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkZvc3NvcmlhbCAywrBDKCUpIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkdyb3VuZC1kd2VsbGluZyAywrBDICglKSIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTZW1pLWFxdWF0aWMgMsKwQyAoJSkiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiU3RyZWFtLWR3ZWxsaW5nIDLCsEMgKCUpIiksCiAgICAgICAgICAgICAgICBkaWdpdHMgPSAyKSAjIDIgZGVjaW1hbCBwbGFjZXMKYGBgCgojIyMgNMKwQyBBSSByaXNrIHsudGFic2V0IC50YWJzZXQtZmFkZSAudGFic2V0LXBpbGxzIC19IAoKUGVyY2VudCBjaGFuZ2UgaW4gYXJpZGl0eSBieSAyMDgw4oCTMjEwMCAoKyA0wrBDKSByZWxhdGl2ZSB0byBjdXJyZW50IGNsaW1hdGUgKDE5ODHigJMyMDEwKSBmb3IgYWxsIGFudXJhbnMgYW5kIGJ5IGVjb3R5cGUuCgpgYGB7ciBhaSBzdW0gNCwgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRX0KIyBjYWxjdWxhdGUgcmVsYXRpdmUgY2hhbmdlIHdpdGggZnV0dXJlIHNjZW5hcmlvCmFpX3NwX3N1bSAlPiUKICBkcGx5cjo6bXV0YXRlKGFsbF9jaGFuZ2UgICAgICAgPSAoYWlfNENfc3Bfc3VtJHNwZWNpZXNfbiAtIHNwZWNpZXNfbikgLyBzcGVjaWVzX24gKiAxMDAsCiAgICAgICAgICAgICAgICBhcXVhdGljX2NoYW5nZSAgID0gKGFpXzRDX3NwX3N1bSRhcXVhdGljX24gLSBhcXVhdGljX24pIC8gYXF1YXRpY19uICogMTAwLAogICAgICAgICAgICAgICAgYXJib3JlYWxfY2hhbmdlICA9IChhaV80Q19zcF9zdW0kYXJib3JlYWxfbiAtIGFyYm9yZWFsX24pIC8gYXJib3JlYWxfbiAqIDEwMCwKICAgICAgICAgICAgICAgIGZvc3NvcmlhbF9jaGFuZ2UgPSAoYWlfNENfc3Bfc3VtJGZvc3NvcmlhbF9uIC0gZm9zc29yaWFsX24pIC8gZm9zc29yaWFsX24gKiAxMDAsCiAgICAgICAgICAgICAgICBncm91bmRfY2hhbmdlICAgID0gKGFpXzRDX3NwX3N1bSRncm91bmRfbiAtIGdyb3VuZF9uKSAvIGdyb3VuZF9uICogMTAwLAogICAgICAgICAgICAgICAgc2VtaV9hcV9jaGFuZ2UgICA9IChhaV80Q19zcF9zdW0kc2VtaV9hcV9uIC0gc2VtaV9hcV9uKSAvIHNlbWlfYXFfbiAqIDEwMCwKICAgICAgICAgICAgICAgIHN0cmVhbV9jaGFuZ2UgICAgPSAoYWlfNENfc3Bfc3VtJHN0cmVhbV9uIC0gc3RyZWFtX24pIC8gc3RyZWFtX24gKiAxMDApICU+JQogIGRwbHlyOjpzZWxlY3QoYyhjYXRlZ29yeSwgYWxsX2NoYW5nZTpzdHJlYW1fY2hhbmdlKSkgJT4lCiAga25pdHI6OmthYmxlKGNvbC5uYW1lcyA9IGMoIkVjb3R5cGUiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQWxsICglKSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkFxdWF0aWMgMsKwQyAoJSkiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQXJib3JlYWwgMsKwQyAoJSkiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRm9zc29yaWFsIDLCsEMoJSkiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiR3JvdW5kLWR3ZWxsaW5nIDLCsEMgKCUpIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlNlbWktYXF1YXRpYyAywrBDICglKSIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTdHJlYW0tZHdlbGxpbmcgMsKwQyAoJSkiKSwKICAgICAgICAgICAgICAgIGRpZ2l0cyA9IDIpICMgMiBkZWNpbWFsIHBsYWNlcwpgYGAKCgojIyMgMsKwQyBQRFNJICByaXNrIHsudGFic2V0IC50YWJzZXQtZmFkZSAudGFic2V0LXBpbGxzIC19IAoKUGVyY2VudCBjaGFuZ2UgaW4gZHJvdWdodCBpbnRlbnNpdHkgKM6UUERTSSksIGZyZXF1ZW5jeSAozpRGcmVxdWVuY3kpLCBhbmQgZHVyYXRpb24gKM6URHVyYXRpb24pIGJ5IDIwODDigJMyMDk5ICgrIDLCsEMgc2NlbmFyaW8pIHJlbGF0aXZlIHRvIGN1cnJlbnQgY2xpbWF0ZSAoMTk3MOKAkzIwMDApIGluIGdyaWQgY2VsbHMgb2NjdXBpZWQgYnkgYW51cmFucyBhbmQgYnkgZWNvdHlwZS4KCmBgYHtyIFBEU0kgc3VtIDIsIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0V9CiNJbnRlbnNpdHkKUERTSV9zcF8yQyAlPiUKICBkcGx5cjo6c2VsZWN0KGMoY2hhbmdlXzJDLCBhbGxfZnJlcTpzdHJlYW1fZnJlcSkpICU+JQogIGtuaXRyOjprYWJsZShjb2wubmFtZXMgPSBjKCLOlFBEU0kiLCAiQWxsICglKSIsICJBcXVhdGljICglKSIsICJBcmJvcmVhbCAoJSkiLCAiRm9zc29yaWFsICglKSIsICJHcm91bmQtZHdlbGxpbmcgKCUpIiwgIlNlbWktYXF1YXRpYyAoJSkiLCAiU3RyZWFtLWR3ZWxsaW5nICglKSIpLAogICAgICAgICAgICAgICAgZGlnaXRzID0gMikgIyAyIGRlY2ltYWwgcGxhY2VzCgojIEZyZXF1ZW5jeQpmcmVxXzJDX2RpZmZfZGYgPC0gZnJlcV9kaWZmX2RmICU+JQogIGRwbHlyOjpzZWxlY3QoeCwgeSwgZGlmZl8yQykgJT4lCiAgZHBseXI6Om11dGF0ZShkaWZmXzJDX2NhdCA9IGNhc2Vfd2hlbigKICAgIGRpZmZfMkMgPj0gMTAgfiAiMTAtMTIiLCAKICAgIGRpZmZfMkMgPj0gOCAmIGRpZmZfMkMgPCAxMCB+ICc4LTEwJywKICAgIGRpZmZfMkMgPj0gNiAmIGRpZmZfMkMgPCA4IH4gJzYtOCcsICAKICAgIGRpZmZfMkMgPj0gNCAmIGRpZmZfMkMgPCA2IH4gJzQtNicsICAKICAgIGRpZmZfMkMgPj0gMiAmIGRpZmZfMkMgPCA0IH4gJzItNCcsCiAgICBkaWZmXzJDID49IDEgJiBkaWZmXzJDIDwgMiB+ICcxLTInLAogICAgZGlmZl8yQyA+IDAgJiBkaWZmXzJDIDwgMSB+ICcwLTEnLAogICAgZGlmZl8yQyA+PSAtMSAmIGRpZmZfMkMgPCAwIH4gJy0wLTEnLAogICAgZGlmZl8yQyA+PSAtMiAmIGRpZmZfMkMgPCAtMSB+ICctMS0yJywKICAgIGRpZmZfMkMgPj0gLTQgJiBkaWZmXzJDIDwgLTIgfiAnLTItNCcKICApKSAlPiUgCiAgZHBseXI6Om11dGF0ZShkaWZmXzJDX2NhdCA9IGZhY3RvcihkaWZmXzJDX2NhdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSBjKCcxMC0xMicsICc4LTEwJywgJzYtOCcsICc0LTYnLCAnMi00JywgJzEtMicsICcwLTEnLCAnLTAtMScsICctMS0yJywgJy0yLTQnKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcmRlcmVkID0gVFJVRSkpCgpmcmVxX3NwXzJDX2RmIDwtIGFudXJhbl9zcl9kZiAlPiUgCiAgZHBseXI6OmZ1bGxfam9pbihmcmVxXzJDX2RpZmZfZGYsIGJ5ID0gYygieCIgLCJ5IikpICU+JSAKICBkcGx5cjo6ZnVsbF9qb2luKGFxdWF0aWNfc3JfZGYsIGJ5ID0gYygieCIgLCJ5IikpICU+JSAKICBkcGx5cjo6ZnVsbF9qb2luKGFyYm9yZWFsX3NyX2RmLCBieSA9IGMoIngiICwieSIpKSAlPiUgCiAgZHBseXI6OmZ1bGxfam9pbihmb3Nzb3JpYWxfc3JfZGYsIGJ5ID0gYygieCIgLCJ5IikpICU+JSAKICBkcGx5cjo6ZnVsbF9qb2luKGdyb3VuZF9zcl9kZiwgYnkgPSBjKCJ4IiAsInkiKSkgJT4lIAogIGRwbHlyOjpmdWxsX2pvaW4oc2VtaV9hcV9zcl9kZiwgYnkgPSBjKCJ4IiAsInkiKSkgJT4lIAogIGRwbHlyOjpmdWxsX2pvaW4oc3RyZWFtX3NyX2RmLCBieSA9IGMoIngiICwieSIpKSAlPiUKICBmaWx0ZXIoZGlmZl8yQ19jYXQgIT0gIk5BIiAmIHNwZWNpZXNfbiAhPSAiTkEiKQoKZGF0YS5mcmFtZShmcmVxX3NwXzJDX2RmICU+JSAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRwbHlyOjpncm91cF9ieShkaWZmXzJDX2NhdCkgJT4lIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZHBseXI6OnN1bW1hcmlzZShzcGVjaWVzX24gICA9IGxlbmd0aChzcGVjaWVzX25bIWlzLm5hKHNwZWNpZXNfbildKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXF1YXRpY19uICAgPSBsZW5ndGgoYXF1YXRpY19uWyFpcy5uYShhcXVhdGljX24pXSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFyYm9yZWFsX24gID0gbGVuZ3RoKGFyYm9yZWFsX25bIWlzLm5hKGFyYm9yZWFsX24pXSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvc3NvcmlhbF9uID0gbGVuZ3RoKGZvc3NvcmlhbF9uWyFpcy5uYShmb3Nzb3JpYWxfbildKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ3JvdW5kX24gICAgPSBsZW5ndGgoZ3JvdW5kX25bIWlzLm5hKGdyb3VuZF9uKV0pLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZW1pX2FxX24gICA9IGxlbmd0aChzZW1pX2FxX25bIWlzLm5hKHNlbWlfYXFfbildKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyZWFtX24gICAgPSBsZW5ndGgoc3RyZWFtX25bIWlzLm5hKHN0cmVhbV9uKV0pKSkgJT4lCiAgZHBseXI6Om11dGF0ZShhbGxfZnJlcSAgICAgICA9IHNwZWNpZXNfbiAvIHN1bShzcGVjaWVzX24pICogMTAwLAogICAgICAgICAgICAgICAgYXF1YXRpY19mcmVxICAgPSBhcXVhdGljX24gLyBzdW0oYXF1YXRpY19uKSAqIDEwMCwKICAgICAgICAgICAgICAgIGFyYm9yZWFsX2ZyZXEgID0gYXJib3JlYWxfbiAvIHN1bShhcmJvcmVhbF9uKSAqIDEwMCwKICAgICAgICAgICAgICAgIGZvc3NvcmlhbF9mcmVxID0gZm9zc29yaWFsX24gLyBzdW0oZm9zc29yaWFsX24pICogMTAwLAogICAgICAgICAgICAgICAgZ3JvdW5kX2ZyZXEgICAgPSBncm91bmRfbiAvIHN1bShncm91bmRfbikgKiAxMDAsCiAgICAgICAgICAgICAgICBzZW1pX2FxX2ZyZXEgICA9IHNlbWlfYXFfbiAvIHN1bShzZW1pX2FxX24pICogMTAwLAogICAgICAgICAgICAgICAgc3RyZWFtX2ZyZXEgICAgPSBzdHJlYW1fbiAvIHN1bShzdHJlYW1fbikgKiAxMDApICU+JQogIGRwbHlyOjpzZWxlY3QoYyhkaWZmXzJDX2NhdCwgYWxsX2ZyZXE6c3RyZWFtX2ZyZXEpKSAlPiUKICAga25pdHI6OmthYmxlKGNvbC5uYW1lcyA9IGMoIs6URnJlcXVlbmN5IChtb250aHMpIiwgIkFsbCAoJSkiLCAiQXF1YXRpYyAoJSkiLCAiQXJib3JlYWwgKCUpIiwgIkZvc3NvcmlhbCAoJSkiLCAiR3JvdW5kLWR3ZWxsaW5nICglKSIsICJTZW1pLWFxdWF0aWMgKCUpIiwgIlN0cmVhbS1kd2VsbGluZyAoJSkiKSwKICAgICAgICAgICAgICAgIGRpZ2l0cyA9IDIpICMgMiBkZWNpbWFsIHBsYWNlcwoKIyBEdXJhdGlvbgpkdXJfMkNfZGlmZl9kZiA8LSBkdXJfZGlmZl9kZiAlPiUKICBkcGx5cjo6c2VsZWN0KHgsIHksIGRpZmZfMkMpICU+JQogIGRwbHlyOjptdXRhdGUoZGlmZl8yQ19jYXQgPSBjYXNlX3doZW4oCiAgICBkaWZmXzJDID49IDEwIH4gIj4xMCIsIAogICAgZGlmZl8yQyA+PSA4ICYgZGlmZl8yQyA8IDEwIH4gJzgtMTAnLAogICAgZGlmZl8yQyA+PSA2ICYgZGlmZl8yQyA8IDggfiAnNi04JywgIAogICAgZGlmZl8yQyA+PSA0ICYgZGlmZl8yQyA8IDYgfiAnNC02JywgIAogICAgZGlmZl8yQyA+PSAyICYgZGlmZl8yQyA8IDQgfiAnMi00JywKICAgIGRpZmZfMkMgPj0gMSAmIGRpZmZfMkMgPCAyIH4gJzEtMicsCiAgICBkaWZmXzJDID4gMCAmIGRpZmZfMkMgPCAxIH4gJzAtMScsCiAgICBkaWZmXzJDID49IC0xICYgZGlmZl8yQyA8IDAgfiAnLTAtMScsCiAgICBkaWZmXzJDID49IC0yICYgZGlmZl8yQyA8IC0xIH4gJy0xLTInLAogICAgZGlmZl8yQyA+PSAtNCAmIGRpZmZfMkMgPCAtMiB+ICctMi00JywKICAgIGRpZmZfMkMgPj0gLTYgJiBkaWZmXzJDIDwgLTQgfiAnLTQtNicsCiAgICBkaWZmXzJDID49IC04ICYgZGlmZl8yQyA8IC02IH4gJy02LTgnLAogICAgZGlmZl8yQyA+PSAtMTAgJiBkaWZmXzJDIDwgLTggfiAnLTgtMTAnLCAgIAogICAgZGlmZl8yQyA8IC0xMCB+ICc8LTEwJyAKICApKSAlPiUgCiAgZHBseXI6Om11dGF0ZShkaWZmXzJDX2NhdCA9IGZhY3RvcihkaWZmXzJDX2NhdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSBjKCc+MTAnLCAnOC0xMCcsICc2LTgnLCAnNC02JywgJzItNCcsICcxLTInLCAnMC0xJywgJy0wLTEnLCAnLTEtMicsICctMi00JywgJy00LTYnLCAnLTYtOCcsICctOC0xMCcsICc8LTEwJyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3JkZXJlZCA9IFRSVUUpKQoKZHVyX3NwXzJDX2RmIDwtIGFudXJhbl9zcl9kZiAlPiUgCiAgZHBseXI6OmZ1bGxfam9pbihkdXJfMkNfZGlmZl9kZiwgYnkgPSBjKCJ4IiAsInkiKSkgJT4lIAogIGRwbHlyOjpmdWxsX2pvaW4oYXF1YXRpY19zcl9kZiwgYnkgPSBjKCJ4IiAsInkiKSkgJT4lIAogIGRwbHlyOjpmdWxsX2pvaW4oYXJib3JlYWxfc3JfZGYsIGJ5ID0gYygieCIgLCJ5IikpICU+JSAKICBkcGx5cjo6ZnVsbF9qb2luKGZvc3NvcmlhbF9zcl9kZiwgYnkgPSBjKCJ4IiAsInkiKSkgJT4lIAogIGRwbHlyOjpmdWxsX2pvaW4oZ3JvdW5kX3NyX2RmLCBieSA9IGMoIngiICwieSIpKSAlPiUgCiAgZHBseXI6OmZ1bGxfam9pbihzZW1pX2FxX3NyX2RmLCBieSA9IGMoIngiICwieSIpKSAlPiUgCiAgZHBseXI6OmZ1bGxfam9pbihzdHJlYW1fc3JfZGYsIGJ5ID0gYygieCIgLCJ5IikpICU+JQogIGZpbHRlcihkaWZmXzJDX2NhdCAhPSAiTkEiICYgc3BlY2llc19uICE9ICJOQSIpCgpkYXRhLmZyYW1lKGR1cl9zcF8yQ19kZiAlPiUgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkcGx5cjo6Z3JvdXBfYnkoZGlmZl8yQ19jYXQpICU+JSAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRwbHlyOjpzdW1tYXJpc2Uoc3BlY2llc19uICAgPSBsZW5ndGgoc3BlY2llc19uWyFpcy5uYShzcGVjaWVzX24pXSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFxdWF0aWNfbiAgID0gbGVuZ3RoKGFxdWF0aWNfblshaXMubmEoYXF1YXRpY19uKV0pLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcmJvcmVhbF9uICA9IGxlbmd0aChhcmJvcmVhbF9uWyFpcy5uYShhcmJvcmVhbF9uKV0pLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3Nzb3JpYWxfbiA9IGxlbmd0aChmb3Nzb3JpYWxfblshaXMubmEoZm9zc29yaWFsX24pXSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdyb3VuZF9uICAgID0gbGVuZ3RoKGdyb3VuZF9uWyFpcy5uYShncm91bmRfbildKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VtaV9hcV9uICAgPSBsZW5ndGgoc2VtaV9hcV9uWyFpcy5uYShzZW1pX2FxX24pXSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmVhbV9uICAgID0gbGVuZ3RoKHN0cmVhbV9uWyFpcy5uYShzdHJlYW1fbildKSkpICU+JQogIGRwbHlyOjptdXRhdGUoYWxsX2ZyZXEgICAgICAgPSBzcGVjaWVzX24gLyBzdW0oc3BlY2llc19uKSAqIDEwMCwKICAgICAgICAgICAgICAgIGFxdWF0aWNfZnJlcSAgID0gYXF1YXRpY19uIC8gc3VtKGFxdWF0aWNfbikgKiAxMDAsCiAgICAgICAgICAgICAgICBhcmJvcmVhbF9mcmVxICA9IGFyYm9yZWFsX24gLyBzdW0oYXJib3JlYWxfbikgKiAxMDAsCiAgICAgICAgICAgICAgICBmb3Nzb3JpYWxfZnJlcSA9IGZvc3NvcmlhbF9uIC8gc3VtKGZvc3NvcmlhbF9uKSAqIDEwMCwKICAgICAgICAgICAgICAgIGdyb3VuZF9mcmVxICAgID0gZ3JvdW5kX24gLyBzdW0oZ3JvdW5kX24pICogMTAwLAogICAgICAgICAgICAgICAgc2VtaV9hcV9mcmVxICAgPSBzZW1pX2FxX24gLyBzdW0oc2VtaV9hcV9uKSAqIDEwMCwKICAgICAgICAgICAgICAgIHN0cmVhbV9mcmVxICAgID0gc3RyZWFtX24gLyBzdW0oc3RyZWFtX24pICogMTAwKSAlPiUKICBkcGx5cjo6c2VsZWN0KGMoZGlmZl8yQ19jYXQsIGFsbF9mcmVxOnN0cmVhbV9mcmVxKSkgJT4lCiAgIGtuaXRyOjprYWJsZShjb2wubmFtZXMgPSBjKCLOlER1cmF0aW9uIChtb250aHMpIiwgIkFsbCAoJSkiLCAiQXF1YXRpYyAoJSkiLCAiQXJib3JlYWwgKCUpIiwgIkZvc3NvcmlhbCAoJSkiLCAiR3JvdW5kLWR3ZWxsaW5nICglKSIsICJTZW1pLWFxdWF0aWMgKCUpIiwgIlN0cmVhbS1kd2VsbGluZyAoJSkiKSwKICAgICAgICAgICAgICAgIGRpZ2l0cyA9IDIpICMgMiBkZWNpbWFsIHBsYWNlcwpgYGAKCiMjIyA0wrBDIFBEU0kgcmlzayB7LnRhYnNldCAudGFic2V0LWZhZGUgLnRhYnNldC1waWxscyAtfSAKClBlcmNlbnQgY2hhbmdlIGluIGRyb3VnaHQgaW50ZW5zaXR5ICjOlFBEU0kpLCBmcmVxdWVuY3kgKM6URnJlcXVlbmN5KSwgYW5kIGR1cmF0aW9uICjOlER1cmF0aW9uKSBieSAyMDgw4oCTMjA5OSAoKyA0wrBDIHNjZW5hcmlvKSByZWxhdGl2ZSB0byBjdXJyZW50IGNsaW1hdGUgKDE5NzDigJMyMDAwKSBpbiBncmlkIGNlbGxzIG9jY3VwaWVkIGJ5IGFudXJhbnMgYW5kIGJ5IGVjb3R5cGUuCgpgYGB7ciBQRFNJIHN1bSA0LCBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQojSW50ZW5zaXR5ClBEU0lfc3BfNEMgJT4lCiAgZHBseXI6OnNlbGVjdChjKGNoYW5nZV80QywgYWxsX2ZyZXE6c3RyZWFtX2ZyZXEpKSAlPiUKICBrbml0cjo6a2FibGUoY29sLm5hbWVzID0gYygizpRQRFNJIiwgIkFsbCAoJSkiLCAiQXF1YXRpYyAoJSkiLCAiQXJib3JlYWwgKCUpIiwgIkZvc3NvcmlhbCAoJSkiLCAiR3JvdW5kLWR3ZWxsaW5nICglKSIsICJTZW1pLWFxdWF0aWMgKCUpIiwgIlN0cmVhbS1kd2VsbGluZyAoJSkiKSwKICAgICAgICAgICAgICAgIGRpZ2l0cyA9IDIpICMgMiBkZWNpbWFsIHBsYWNlcwoKIyBGcmVxdWVuY3kKZnJlcV80Q19kaWZmX2RmIDwtIGZyZXFfZGlmZl9kZiAlPiUKICBkcGx5cjo6c2VsZWN0KHgsIHksIGRpZmZfNEMpICU+JQogIGRwbHlyOjptdXRhdGUoZGlmZl80Q19jYXQgPSBjYXNlX3doZW4oCiAgICBkaWZmXzRDID49IDEwIH4gIjEwLTEyIiwgCiAgICBkaWZmXzRDID49IDggJiBkaWZmXzRDIDwgMTAgfiAnOC0xMCcsCiAgICBkaWZmXzRDID49IDYgJiBkaWZmXzRDIDwgOCB+ICc2LTgnLCAgCiAgICBkaWZmXzRDID49IDQgJiBkaWZmXzRDIDwgNiB+ICc0LTYnLCAgCiAgICBkaWZmXzRDID49IDIgJiBkaWZmXzRDIDwgNCB+ICcyLTQnLAogICAgZGlmZl80QyA+PSAxICYgZGlmZl80QyA8IDIgfiAnMS0yJywKICAgIGRpZmZfNEMgPiAwICYgZGlmZl80QyA8IDEgfiAnMC0xJywKICAgIGRpZmZfNEMgPj0gLTEgJiBkaWZmXzRDIDwgMCB+ICctMC0xJywKICAgIGRpZmZfNEMgPj0gLTIgJiBkaWZmXzRDIDwgLTEgfiAnLTEtMicsCiAgICBkaWZmXzRDID49IC00ICYgZGlmZl80QyA8IC0yIH4gJy0yLTQnCiAgKSkgJT4lIAogIGRwbHlyOjptdXRhdGUoZGlmZl80Q19jYXQgPSBmYWN0b3IoZGlmZl80Q19jYXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV2ZWxzID0gYygnMTAtMTInLCAnOC0xMCcsICc2LTgnLCAnNC02JywgJzItNCcsICcxLTInLCAnMC0xJywgJy0wLTEnLCAnLTEtMicsICctMi00JyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3JkZXJlZCA9IFRSVUUpKQoKZnJlcV9zcF80Q19kZiA8LSBhbnVyYW5fc3JfZGYgJT4lIAogIGRwbHlyOjpmdWxsX2pvaW4oZnJlcV80Q19kaWZmX2RmLCBieSA9IGMoIngiICwieSIpKSAlPiUgCiAgZHBseXI6OmZ1bGxfam9pbihhcXVhdGljX3NyX2RmLCBieSA9IGMoIngiICwieSIpKSAlPiUgCiAgZHBseXI6OmZ1bGxfam9pbihhcmJvcmVhbF9zcl9kZiwgYnkgPSBjKCJ4IiAsInkiKSkgJT4lIAogIGRwbHlyOjpmdWxsX2pvaW4oZm9zc29yaWFsX3NyX2RmLCBieSA9IGMoIngiICwieSIpKSAlPiUgCiAgZHBseXI6OmZ1bGxfam9pbihncm91bmRfc3JfZGYsIGJ5ID0gYygieCIgLCJ5IikpICU+JSAKICBkcGx5cjo6ZnVsbF9qb2luKHNlbWlfYXFfc3JfZGYsIGJ5ID0gYygieCIgLCJ5IikpICU+JSAKICBkcGx5cjo6ZnVsbF9qb2luKHN0cmVhbV9zcl9kZiwgYnkgPSBjKCJ4IiAsInkiKSkgJT4lCiAgZmlsdGVyKGRpZmZfNENfY2F0ICE9ICJOQSIgJiBzcGVjaWVzX24gIT0gIk5BIikKCmRhdGEuZnJhbWUoZnJlcV9zcF80Q19kZiAlPiUgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkcGx5cjo6Z3JvdXBfYnkoZGlmZl80Q19jYXQpICU+JSAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRwbHlyOjpzdW1tYXJpc2Uoc3BlY2llc19uICAgPSBsZW5ndGgoc3BlY2llc19uWyFpcy5uYShzcGVjaWVzX24pXSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFxdWF0aWNfbiAgID0gbGVuZ3RoKGFxdWF0aWNfblshaXMubmEoYXF1YXRpY19uKV0pLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcmJvcmVhbF9uICA9IGxlbmd0aChhcmJvcmVhbF9uWyFpcy5uYShhcmJvcmVhbF9uKV0pLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3Nzb3JpYWxfbiA9IGxlbmd0aChmb3Nzb3JpYWxfblshaXMubmEoZm9zc29yaWFsX24pXSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdyb3VuZF9uICAgID0gbGVuZ3RoKGdyb3VuZF9uWyFpcy5uYShncm91bmRfbildKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VtaV9hcV9uICAgPSBsZW5ndGgoc2VtaV9hcV9uWyFpcy5uYShzZW1pX2FxX24pXSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmVhbV9uICAgID0gbGVuZ3RoKHN0cmVhbV9uWyFpcy5uYShzdHJlYW1fbildKSkpICU+JQogIGRwbHlyOjptdXRhdGUoYWxsX2ZyZXEgICAgICAgPSBzcGVjaWVzX24gLyBzdW0oc3BlY2llc19uKSAqIDEwMCwKICAgICAgICAgICAgICAgIGFxdWF0aWNfZnJlcSAgID0gYXF1YXRpY19uIC8gc3VtKGFxdWF0aWNfbikgKiAxMDAsCiAgICAgICAgICAgICAgICBhcmJvcmVhbF9mcmVxICA9IGFyYm9yZWFsX24gLyBzdW0oYXJib3JlYWxfbikgKiAxMDAsCiAgICAgICAgICAgICAgICBmb3Nzb3JpYWxfZnJlcSA9IGZvc3NvcmlhbF9uIC8gc3VtKGZvc3NvcmlhbF9uKSAqIDEwMCwKICAgICAgICAgICAgICAgIGdyb3VuZF9mcmVxICAgID0gZ3JvdW5kX24gLyBzdW0oZ3JvdW5kX24pICogMTAwLAogICAgICAgICAgICAgICAgc2VtaV9hcV9mcmVxICAgPSBzZW1pX2FxX24gLyBzdW0oc2VtaV9hcV9uKSAqIDEwMCwKICAgICAgICAgICAgICAgIHN0cmVhbV9mcmVxICAgID0gc3RyZWFtX24gLyBzdW0oc3RyZWFtX24pICogMTAwKSAlPiUKICBkcGx5cjo6c2VsZWN0KGMoZGlmZl80Q19jYXQsIGFsbF9mcmVxOnN0cmVhbV9mcmVxKSkgJT4lCiAgIGtuaXRyOjprYWJsZShjb2wubmFtZXMgPSBjKCLOlEZyZXF1ZW5jeSAobW9udGhzKSIsICJBbGwgKCUpIiwgIkFxdWF0aWMgKCUpIiwgIkFyYm9yZWFsICglKSIsICJGb3Nzb3JpYWwgKCUpIiwgIkdyb3VuZC1kd2VsbGluZyAoJSkiLCAiU2VtaS1hcXVhdGljICglKSIsICJTdHJlYW0tZHdlbGxpbmcgKCUpIiksCiAgICAgICAgICAgICAgICBkaWdpdHMgPSAyKSAjIDIgZGVjaW1hbCBwbGFjZXMKCiMgRHVyYXRpb24KZHVyXzRDX2RpZmZfZGYgPC0gZHVyX2RpZmZfZGYgJT4lCiAgZHBseXI6OnNlbGVjdCh4LCB5LCBkaWZmXzRDKSAlPiUKICBkcGx5cjo6bXV0YXRlKGRpZmZfNENfY2F0ID0gY2FzZV93aGVuKAogICAgZGlmZl80QyA+PSAxMCB+ICI+MTAiLCAKICAgIGRpZmZfNEMgPj0gOCAmIGRpZmZfNEMgPCAxMCB+ICc4LTEwJywKICAgIGRpZmZfNEMgPj0gNiAmIGRpZmZfNEMgPCA4IH4gJzYtOCcsICAKICAgIGRpZmZfNEMgPj0gNCAmIGRpZmZfNEMgPCA2IH4gJzQtNicsICAKICAgIGRpZmZfNEMgPj0gMiAmIGRpZmZfNEMgPCA0IH4gJzItNCcsCiAgICBkaWZmXzRDID49IDEgJiBkaWZmXzRDIDwgMiB+ICcxLTInLAogICAgZGlmZl80QyA+IDAgJiBkaWZmXzRDIDwgMSB+ICcwLTEnLAogICAgZGlmZl80QyA+PSAtMSAmIGRpZmZfNEMgPCAwIH4gJy0wLTEnLAogICAgZGlmZl80QyA+PSAtMiAmIGRpZmZfNEMgPCAtMSB+ICctMS0yJywKICAgIGRpZmZfNEMgPj0gLTQgJiBkaWZmXzRDIDwgLTIgfiAnLTItNCcsCiAgICBkaWZmXzRDID49IC02ICYgZGlmZl80QyA8IC00IH4gJy00LTYnLAogICAgZGlmZl80QyA+PSAtOCAmIGRpZmZfNEMgPCAtNiB+ICctNi04JywKICAgIGRpZmZfNEMgPj0gLTEwICYgZGlmZl80QyA8IC04IH4gJy04LTEwJywgICAKICAgIGRpZmZfNEMgPCAtMTAgfiAnPC0xMCcgCiAgKSkgJT4lIAogIGRwbHlyOjptdXRhdGUoZGlmZl80Q19jYXQgPSBmYWN0b3IoZGlmZl80Q19jYXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV2ZWxzID0gYygnPjEwJywgJzgtMTAnLCAnNi04JywgJzQtNicsICcyLTQnLCAnMS0yJywgJzAtMScsICctMC0xJywgJy0xLTInLCAnLTItNCcsICctNC02JywgJy02LTgnLCAnLTgtMTAnLCAnPC0xMCcpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9yZGVyZWQgPSBUUlVFKSkKCmR1cl9zcF80Q19kZiA8LSBhbnVyYW5fc3JfZGYgJT4lIAogIGRwbHlyOjpmdWxsX2pvaW4oZHVyXzRDX2RpZmZfZGYsIGJ5ID0gYygieCIgLCJ5IikpICU+JSAKICBkcGx5cjo6ZnVsbF9qb2luKGFxdWF0aWNfc3JfZGYsIGJ5ID0gYygieCIgLCJ5IikpICU+JSAKICBkcGx5cjo6ZnVsbF9qb2luKGFyYm9yZWFsX3NyX2RmLCBieSA9IGMoIngiICwieSIpKSAlPiUgCiAgZHBseXI6OmZ1bGxfam9pbihmb3Nzb3JpYWxfc3JfZGYsIGJ5ID0gYygieCIgLCJ5IikpICU+JSAKICBkcGx5cjo6ZnVsbF9qb2luKGdyb3VuZF9zcl9kZiwgYnkgPSBjKCJ4IiAsInkiKSkgJT4lIAogIGRwbHlyOjpmdWxsX2pvaW4oc2VtaV9hcV9zcl9kZiwgYnkgPSBjKCJ4IiAsInkiKSkgJT4lIAogIGRwbHlyOjpmdWxsX2pvaW4oc3RyZWFtX3NyX2RmLCBieSA9IGMoIngiICwieSIpKSAlPiUKICBmaWx0ZXIoZGlmZl80Q19jYXQgIT0gIk5BIiAmIHNwZWNpZXNfbiAhPSAiTkEiKQoKZGF0YS5mcmFtZShkdXJfc3BfNENfZGYgJT4lIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZHBseXI6Omdyb3VwX2J5KGRpZmZfNENfY2F0KSAlPiUgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkcGx5cjo6c3VtbWFyaXNlKHNwZWNpZXNfbiAgID0gbGVuZ3RoKHNwZWNpZXNfblshaXMubmEoc3BlY2llc19uKV0pLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcXVhdGljX24gICA9IGxlbmd0aChhcXVhdGljX25bIWlzLm5hKGFxdWF0aWNfbildKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJib3JlYWxfbiAgPSBsZW5ndGgoYXJib3JlYWxfblshaXMubmEoYXJib3JlYWxfbildKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9zc29yaWFsX24gPSBsZW5ndGgoZm9zc29yaWFsX25bIWlzLm5hKGZvc3NvcmlhbF9uKV0pLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBncm91bmRfbiAgICA9IGxlbmd0aChncm91bmRfblshaXMubmEoZ3JvdW5kX24pXSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbWlfYXFfbiAgID0gbGVuZ3RoKHNlbWlfYXFfblshaXMubmEoc2VtaV9hcV9uKV0pLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJlYW1fbiAgICA9IGxlbmd0aChzdHJlYW1fblshaXMubmEoc3RyZWFtX24pXSkpKSAlPiUKICBkcGx5cjo6bXV0YXRlKGFsbF9mcmVxICAgICAgID0gc3BlY2llc19uIC8gc3VtKHNwZWNpZXNfbikgKiAxMDAsCiAgICAgICAgICAgICAgICBhcXVhdGljX2ZyZXEgICA9IGFxdWF0aWNfbiAvIHN1bShhcXVhdGljX24pICogMTAwLAogICAgICAgICAgICAgICAgYXJib3JlYWxfZnJlcSAgPSBhcmJvcmVhbF9uIC8gc3VtKGFyYm9yZWFsX24pICogMTAwLAogICAgICAgICAgICAgICAgZm9zc29yaWFsX2ZyZXEgPSBmb3Nzb3JpYWxfbiAvIHN1bShmb3Nzb3JpYWxfbikgKiAxMDAsCiAgICAgICAgICAgICAgICBncm91bmRfZnJlcSAgICA9IGdyb3VuZF9uIC8gc3VtKGdyb3VuZF9uKSAqIDEwMCwKICAgICAgICAgICAgICAgIHNlbWlfYXFfZnJlcSAgID0gc2VtaV9hcV9uIC8gc3VtKHNlbWlfYXFfbikgKiAxMDAsCiAgICAgICAgICAgICAgICBzdHJlYW1fZnJlcSAgICA9IHN0cmVhbV9uIC8gc3VtKHN0cmVhbV9uKSAqIDEwMCkgJT4lCiAgZHBseXI6OnNlbGVjdChjKGRpZmZfNENfY2F0LCBhbGxfZnJlcTpzdHJlYW1fZnJlcSkpICU+JQogICBrbml0cjo6a2FibGUoY29sLm5hbWVzID0gYygizpREdXJhdGlvbiAobW9udGhzKSIsICJBbGwgKCUpIiwgIkFxdWF0aWMgKCUpIiwgIkFyYm9yZWFsICglKSIsICJGb3Nzb3JpYWwgKCUpIiwgIkdyb3VuZC1kd2VsbGluZyAoJSkiLCAiU2VtaS1hcXVhdGljICglKSIsICJTdHJlYW0tZHdlbGxpbmcgKCUpIiksCiAgICAgICAgICAgICAgICBkaWdpdHMgPSAyKSAjIDIgZGVjaW1hbCBwbGFjZXMKYGBgCgojIFN5c3RlbWF0aWMgc2VhcmNoIHstfSAKCiMjIEV4Y2x1c2lvbiBjcml0ZXJpYSB7LX0KCi0gU3R1ZGllcyB3aXRoIGxhbmd1YWdlcyB0aGF0IHdlcmUgbm90IHRyYW5zbGF0YWJsZSBvbiBHb29nbGUgVHJhbnNsYXRlLgotIERhdGEgZnJvbSBleHBlcmltZW50YWwgdHJlYXRtZW50cyBzdWNoIGFzIHBhdGhvZ2VuIGluZmVjdGlvbiwgcG9sbHV0YW50cyBvciBwZXN0aWNpZGUgY29udGFtaW5hbnRzLCBhbmQgcGhhcm1hY29sb2dpY2FsIG1hbmlwdWxhdGlvbiAoZS5nLiwgYW50aWRpdXJldGljIGhvcm1vbmVzKS4KLSBEYXRhIHByZXNlbnRlZCBhcyBwZXJjZW50YWdlIGNoYW5nZSBpbiBib2R5IHdlaWdodCB3aXRob3V0IHRoZSBpbml0aWFsIHdlaWdodC4KLSBEYXRhIHByZXNlbnQgd2l0aCBubyB0aW1lIGNvbXBvbmVudC4gRS5nLiBDaGFuZ2UgaW4gYm9keSB3ZWlnaHQgdW50aWwgMjAlIG9mIHdhdGVyIGxvc3Mgd2FzIHJlYWNoZWQgKCUgY2hhbmdlIGluIG1hc3MpLgotIFN0dWRpZXMgd2hlcmUgdW5pdHMgd2VyZSBub3QgcHJlc2VudGVkLgoKIyMgUHJlZmVycmVkIFJlcG9ydGluZyBJdGVtcyBmb3IgU3lzdGVtYXRpYyBSZXZpZXdzIGFuZCBNZXRhLUFuYWx5c2VzIHstfQoKVGhlIGZvbGxvd2luZyBCb29sZWFuIHNlYXJjaCBzdHJpbmcgZm9yIFdlYiBvZiBTY2llbmNlOiAoZnJvZyBPUiB0b2FkIE9SIGFudXJcKikgQU5EICh3YXRlciBsb3NzIE9SIHdhdGVyIHVwdGFrZSBPUiBldmFwb3JhdGVcKiBPUiBza2luIHJlc2lzdFwqIE9SIGN1dGFuZW91cyBldmFwb1wqKSBBTkQgKGRlaHlkcmF0aW9uIE9SIGRlc2ljY2F0aW9uIE9SIHdhdGVyIE9SIHNvaWwgbW9pc3RcKikgTk9UICh0YWRwb2xlIE9SIGxhcnZhXCogT1IgbWljZSBPUiByYXQgT1IgcGxhbnQsIE9SIHNlZWQgT1IgZmlzaCkgYW5kIGZvciBTY29wdXM6IChUSVRMRS1BQlMtS0VZKGZyb2cgT1IgdG9hZCBPUiBhbnVyXCopICBBTkQgVElUTEUtQUJTLUtFWSh3YXRlciBBTkQgbG9zcyBPUiB3YXRlciBBTkQgdXB0YWtlIE9SIGV2YXBvcmF0ZVwqIE9SIHNraW4gQU5EIHJlc2lzdFwqIE9SIGN1dGFuZW91cyBBTkQgZXZhcG9cKikpIHdlcmUgcGVyZm9ybWVkIG9uIHRoZSAyMSBKdWx5IDIwMjIsIHJlc3VsdGluZyBpbiA0NDkgcmVjb3JkcyBmcm9tIDE5MzggdG8gMjAyMiAoV29TKSwgYW5kIDUxIHJlY29yZHMgZnJvbSAxOTUxIHRvIDIwMjIgKFNjb3B1cykuIFdlIGV4Y2x1ZGVkIHRvcGljcyByZWxhdGVkIHRvIGNoZW1pc3RyeSwgcGh5c2ljYWwsIG1hdGVyaWFscyBzY2llbmNlLCBtZWRpY2FsLCBnZW9sb2d5LCBmaXNoZXJpZXMsIG9jZWFub2dyYXBoeSwgYW5kIGVuZ2luZWVyaW5nLiBUaXRsZSBhbmQgYWJzdHJhY3Qgc2NyZWVuaW5nIG9mIHRoZSBjb21wcmVoZW5zaXZlIHNlYXJjaCB3YXMgY29uZHVjdGVkIGluIFtSYXl5YW5dKGh0dHBzOi8vd3d3LnJheXlhbi5haS8pIFtAT3V6emFuaTIwMTZdLiBGb3J3YXJkIGFuZCBiYWNrd2FyZCBzZWFyY2hlcyB3ZXJlIGFsc28gY29uZHVjdGVkIG9uIEdvb2dsZSBTY2hvbGFyICh1bnRpbCAxNSBBdWcgMjAyMjsgKipGaWcuIFMxKiopIGZvciBhZGRpdGlvbmFsIHBhcGVycywgYW5kIHdlIGFsc28gc2VhcmNoZWQgZm9yIHBhcGVycyBmcm9tIEBGZWRlcjE5OTIsIEBMaWxseXdoaXRlMjAwNiwgYW5kIEBIaWxsbWFuMjAwOS4gTGFzdGx5LCBhZGRpdGlvbmFsIHN0dWRpZXMgKCpuKiA9IDMpIHdlcmUgcHJvdmlkZWQgYnkgdGhlIFN0ZWxsZW5ib3NjaCBVbml2ZXJzaXR5IGxpYnJhcmlhbiAoc2VhcmNoZWQgMXN0IEZlYnVyYXJ5IDIwMjMpLgoKIVtdKEZpZyBTMyAtIFBSSVNNQSBkaWFncmFtLnBuZykKCioqRmlnLiBTMy4qKiBQUklTTUEgZmxvdyBkaWFncmFtIGZvciB0aGUgc3lzdGVtYXRpYyBkYXRhLWNvbGxlY3Rpb24gcHJvY2Vzcy4gKm4qID0gbnVtYmVyIG9mIHBhcGVycyByZW1haW5pbmcgYWZ0ZXIgZWFjaCBzdGFnZSBvZiBzZWxlY3Rpb24uICprKiBpcyB0aGUgbnVtYmVyIG9mIG9ic2VydmF0aW9ucy9yZWNvcmRzLCBhbmQgKm4qIGluIHRoZSBsYXN0IHJvdyBpcyBudW1iZXIgb2Ygc3BlY2llcyBhZnRlciBwcm9jZXNzaW5nIGRhdGEuCgojIyMgRGVmaW5pdGlvbnMgey19CgpXZSBub3RlLCB0aGF0ICJ3YXRlci1wcm9vZiIgaXMgYSBzdWJqZWN0aXZlIHRlcm0sIGFuZCB0aGUgbWVjaGFuaXNtIGlzIG9ubHkgd2VsbCB1bmRlcnN0b29kIGZvciB0aGUgKlBoeWxsb21lZHVzYSogZ2VudXMgd2l0aCB0aGUgcHJlc2VuY2Ugb2Ygd2F4eSBzZWNyZXRpb24gb2YgY3V0YW5lb3VzIGxpcGlkcywgYW5kIHRoZSBzdGVyZW90eXBpY2FsIHdpcGluZyBiZWhhdmlvdXIgW0BCbGF5bG9jazE5NzY7IEBHb21lejIwMDZdLiBPdGhlciBhcmJvcmVhbCBzcGVjaWVzIHNob3cgZHJ5IG11Y3VzIGZpbG0gb24gdGhlIHNraW4gb3IgdGhlIHByZXNlbmNlIG9mIGN1dGFuZW91cyBzdXJhZmNlIGZsdWlkIHRoYXQgbWF5IGNvbnRyaWJ1dGUgdG8gaGlnaCBza2luIHJlc2lzdGFuY2UgW0BLb2JlbHQxOTg2XS4gV2UgbGFiZWxsZWQgZnJvZ3MgYXMgIndhdGVyLXByb29mIiBiYXNlZCBvbiBlYWNoIHN0dWR5J3MgZGVmaW5pdGlvbiwgaS5lLiwgaWYgdGhlIGF1dGhvcnMgZGVzY3JpYmUgdGhlIHNwZWNpZXMgYXMgIndhdGVyLXByb29mIi4gSG93ZXZlciwgbm90IGFsbCAid2F0ZXItcHJvb2YiIGZyb2dzIGV4Y3JldGUgd2F0ZXItcHJvb2Ygc2VjcmV0aW9ucyB0aHJvdWdob3V0IHRoZSB5ZWFyLCBhbmQgbWF5IG9ubHkgc2hvdyB0aGlzIGFkYXB0YXRpb24gZHVyaW5nIGNlcnRhaW4gcGVyaW9kcyBzdWNoIGFzIHRoZSBkcnkgc2Vhc29uIChSLiBQLiBCb3ZvLCBwZXJzLiBjb21tLikuIAoKQW5vdGhlciBicm9hZCBwb3N0LWhvYyBkZWZpbml0aW9uIGZvciBjbGFzc2lmeWluZyB3YXRlci1wcm9vZiBpcyB3aGV0aGVyIHRoZSBza2luIHJlc2lzdGFuY2UgaXMgYWJvdmUgYSBjZXJ0YWluIHRocmVzaG9sZC4gQEhpbGxtYW4yMDA5IGRlZmluZWQgYW51cmFucyBhcyBtb2RlcmF0ZWx5IHdhdGVyLXByb29mIHdpdGggc2tpbiByZXNpc3RhbmNlIGJldHdlZW4gMiB0byAyMCBjbSBzXi0xXiwgYW5kIGhpZ2hseSB3YXRlci1wcm9vZiB3aXRoIHNraW4gcmVzaXN0YW5jZSA+MjAgY20gc14tMV4uIEhvd2V2ZXIsIGV2ZW4gd2l0aGluIHN0dWRpZXMsIHRoZSBzYW1lIHNwZWNpZXMgd2lsbCBzaG93IGRpZmZlcmVudCBza2luIHJlc2lzdGFuY2UgZGVwZW5kaW5nIG9uIHRoZSBlbnZpcm9ubWVudGFsIGV4cG9zdXJlLiBlLmcuIGxvd2VyIHNraW4gcmVzaXN0YW5jZSBhdCBoaWdoZXIgdGVtcGVyYXR1cmUgW0BCdXR0ZW1lcjIwMDNdLiBXZSBpbmNsdWRlZCBib3RoIGRlZmluaXRpb25zIGluIHRoZSByYXcgZGF0YSBmaWxlLCBidXQgdXNlZCB0aGUgcHJpb3IgZGVmaW5pdGlvbiBmb3IgdGhlIGFuYWx5c2lzLgoKRVdMIG1lYXN1cmVtZW50cyBsYWJlbGxlZCB3aXRoICJjb2Nvb24iIGlzIHN0cmFpZ2h0LWZvcndhcmQsIHdpdGggdGhlIHByZXNlbmNlIG9mIGFjY3VtdWxhdGVkIGVwaWRlcm1hbCBsYXllcnMgaW4gYWVzdGl2YXRpbmcgYW51cmFucy4gRVdMIG1lYXN1cmVtZW50cyBsYWJlbGxlZCB3aXRoICJob2xsb3ciIHdlcmUgY29uZHVjdGVkIHdpdGggdGhlIHByZXNlbmNlIG9mIGEgaGlkaW5nIHNwb3QgcHJvdGVjdGluZyB0aGUgZnJvZyBmcm9tIHRoZSBleHBvc2VkIGFpci4KCkFudXJhbnMgYWxzbyBjaGFuZ2UgRVdMIGFjcm9zcyB0aGUgbWVhc3VyZWQgcGVyaW9kIChpLmUuIGRlY3JlYXNlIGluIEVXTCBhcyB0aGV5IGJlY29tZSBtb3JlIGRlaHlkcmF0ZWQpLiBIb3dldmVyLCBtb3N0IHN0dWRpZXMgZWl0aGVyIHRvb2sgYW4gYXZlcmFnZSB2YWx1ZSBvdmVyIHRoZSBleHBlcmltZW50IGR1cmF0aW9uLCBvciBwcmVzZW50ZWQgdGhlIGZpcnN0IGhvdXIgb2YgbWVhc3VyZW1lbnRzLiBXaGVuIHN0dWRpZXMgcHJvdmlkZWQgY2hhbmdlIGluIEVXTCBhdCBkaWZmZXJlbnQgdGltZSBwb2ludHMsIHdlIHRvb2sgdGhlIGZpcnN0IGhvdXIgRVdMIG1lYXN1cmVtZW50cy4gTm90ZSwgYWxtb3N0IGFsbCBhbmltYWxzIHdlcmUgY29uc2lkZXJlZCBmdWxseSBoeWRyYXRlZCBkdXJpbmcgdGhlIHN0YXJ0IG9mIHRoZSBFV0wgZXhwZXJpbWVudCwgd2hlcmUgdGhleSB3ZXJlIHN1Ym1lcnNlZCBvciBnaXZlbiB3YXRlciBwcmlvciB0byB0aGUgRVdMIGV4cGVyaW1lbnQuIAoKIyMgVW5wdWJsaXNoZWQgZGF0YSB7LX0KCkFkZGl0aW9uYWwgRVdMLCBza2luIHJlc2lzdGFuY2UsIGFuZCBXVSBkYXRhIHdlcmUgb2J0YWluZWQgZnJvbSB1bnB1Ymxpc2hlZCBzb3VyY2VzLiBUaGUgKkF0ZWxvcHVzIGNhcnJpa2VyaSogZGF0YSBpcyBhdmFpbGFibGUgb24gYW4gb25saW5lIHJlcG9zaXRvcnkgKFtTb2xhbm8gJiBBbGJlcnQsIDIwMDBdKGh0dHBzOi8vZGF0YS5tZW5kZWxleS5jb20vZGF0YXNldHMvNGM1bmtwcnpjeS8xKSksIGFuZCB0aGUgKlRob3JvcGEgbWlsaWFyaXMqIGRhdGEgY2FuIGJlIG9idGFpbmVkIGZyb20gQy4gTmF2YXMgKG5hdmFzQHVzcC5icikuCgpCcmllZmx5LCB0aGUgbWV0aG9kIGZvciAqQXRlbG9wdXMgY2FycmlrZXJpKiBpcyBkZXNjcmliZWQgYmVsb3c6CgoxNSAqQXRlbG9wdXMgY2FycmlrZXJpKiB3ZXJlIGNvbGxlY3RlZCBuZWFyIHRoZSBiYXNpbiBvZiBQaWNvIENyaXN0w7JiYWwgQ29sw7JuICgxMMKwNTQnMDUuOCJOIDczwrA1NScwMC43IlcpIGFuZCBicm91Z2h0IGJhY2sgdG8gdGhlIFVuaXZlcnNpZGFkIGRlbCBNYWdkYWxlbmEgY2FtcHVzLiBUbyBlc3RpbWF0ZSBldmFwb3JhdGl2ZSB3YXRlciBsb3NzLCBmdWxseSBoeWRyYXRlZCBpbmRpdmlkdWFscyB3ZXJlIGJyaWVmbHkgZHJpZWQgd2l0aCBhYnNvcmJlbnQgcGFwZXIgYW5kIHRoZSB1cmluZSB3YXMgcmVtb3ZlZCBieSBsaWdodGx5IHByZXNzaW5nIHRoZWlyIGFiZG9tZW4gYW5kIHdlaWdoZWQgdG8gb2J0YWluIHRoZSBpbml0aWFsIHdlaWdodC4gRWFjaCBpbmRpdmlkdWFsIHdhcyBwbGFjZWQgaW4gYSB3aW5kIHR1bm5lbCBhdCAyLjQgY20gc14tMV4sIGFuZCB3ZWlnaGVkIGV2ZXJ5IGZpdmUgbWludXRlIHVudGlsIGluZGl2aWR1YWxzIHJlYWNoZWQgNzAtNjUlIG9mIHRoZWlyIGluaXRpYWwgd2VpZ2h0IFtAVGl0b24yMDEwXS4gVGhlIHJhdGUgb2Ygd2F0ZXIgbG9zcyB3YXMgY2FsY3VsYXRlZCBmcm9tIHRoZSB2YWx1ZSBvZiB0aGUgcmVncmVzc2lvbiBvZiB0aGUgd2VpZ2h0IGxvc3Qgb3ZlciB0aW1lIGFuZCBleHByZXNzZWQgaW4gbWcgbWluXi0xXi4gRXZhcG9yYXRpdmUgd2F0ZXIgbG9zcyBjb3JyZWN0ZWQgZm9yIHN1cmZhY2UgYXJlYSB3YXMgY2FsY3VsYXRlZCBieSBkaXZpZGluZyBieSAyLzMgb2YgdGhlIHRvdGFsIHN1cmZhY2UgYXJlYSB3aGljaCBjb3JyZXNwb25kcyB0byB0aGUgcmVnaW9uIG9mIHRoZSBib2R5IGluIGNvbnRhY3Qgd2l0aCB0aGUgYWlyIGZsb3cgKG1nIGNtXi0yXiBtaW5eLTFeKSBbQFdpdGhlcnMxOTgyOyBAVGl0b24yMDEwOyBAVGl0b24yMDE1XS4gCgpUbyBlc3RpbWF0ZSByYXRlIG9mIHdhdGVyIHVwdGFrZSwgSW5kaXZpZHVhbHMgd2hlcmUgcGxhY2VkIGluIGNvbnRhaW5lcnMgd2l0aCBhYnNvcmJlbnQgdG93ZWxzIG1vaXN0ZW5lZCB3aXRoIGVub3VnaCB3YXRlciB0byBjb3ZlciB0aGUgdmVudHJhbCByZWdpb24gYWZ0ZXIgdGhlIGV2YXBvcmF0aXZlIHdhdGVyIGxvc3MgZXhwZXJpbWVudC4gVGhlIGluZGl2aWR1YWxzIHdlcmUgZHJpZWQgYW5kIHdlaWdoZWQgZXZlcnkgZm91ciBtaW51dGVzIGZvciBzaXggY29uc2VjdXRpdmUgdGltZXMgW0BUaXRvbjIwMTA7IEBBbmRlcnNvbjIwMTddLiBUaGUgd2F0ZXIgdXB0YWtlIHJhdGUgcGVyIGFyZWEsIHdhcyBjYWxjdWxhdGVkIGZyb20gdGhlIHZhbHVlIG9mIHRoZSByZWdyZXNzaW9uIG9mIHRoZSBib2R5IHdlaWdodCBnYWluZWQgYXMgYSBmdW5jdGlvbiBvZiB0aW1lIChtZyBtaW5eLTFeKSwgYW5kIGluIHR1cm4gZGl2aWRlZCBieSAxLzMgb2YgdGhlIHRvdGFsIHN1cmZhY2UgYXJlYSB0aGF0IGNvcnJlc3BvbmRzIHRvIHRoZSB2ZW50cmFsIGFyZWEgaW4gY29udGFjdCB3aXRoIHdhdGVyIGR1cmluZyBhYnNvcnB0aW9uLCB0aGUgdmFsdWVzIHdlcmUgZXhwcmVzc2VkIGluIHVuaXRzIG9mIG1nIGNtXi0yXiBtaW5eLTFeLiBBbGwgZXhwZXJpbWVudHMgd2VyZSBjb25kdWN0ZWQgYXQgYW4gYXZlcmFnZSBhaXIgdGVtcGVyYXR1cmUgb2YgMjUuNTUgwrEgMC4yOMKwQy4gVGhlIHJlbGF0aXZlIGh1bWlkaXR5IHdhcyBub3QgbWVhc3VyZWQgYnV0IGFwcG94aW1hdGVkIGJhc2VkIG9uIHRoZSBsb2NhdGlvbiBhbmQgdGltZSBvZiB0aGUgZXhwZXJpbWVudCAoUi4gU29sYW5vIHBlcnMuIGNvbW0uKQoKVGhlIG1ldGhvZCBmb3IgKlRob3JvcGEgbWlsaWFyaXMqIGlzIGRlc2NyaWJlZCBiZWxvdzoKCjE0ICpUaG9yb3BhIG1pbGlhcmlzKiB3ZXJlIGNvbGxlY3RlZCBhcm91bmQgVWJhdHViYSAoYXBwcm94aW1hdGUgbG9jYXRpb24gMjPCsDI24oCyMTPigLNTIDQ1wrAwNOKAsjA44oCzVyksIGFuZCAxNSBpbmRpdmlkdWFscyB3ZXJlIGNvbGxlY3RlZCBpbiB0aGUgU2VycmEgZG8gTWFyIFN0YXRlIFBhcmssIFBpY2luZ3VhYmEgTnVjbGV1cyAoYXBwcm94aW1hdGUgbG9jYXRpb24gMjPCsDI34oCZNTDigJ1TIHRvIDIzwrAxNeKAmTAw4oCdUyBhbmQgNDXCsDE14oCZMDDigJ1XIHRvIDQ0wrA0M+KAmTMw4oCdVykuIEFuaW1hbHMgd2VyZSBicm91Z2h0IGJhY2sgdG8gdGhlIFVuaXZlcnNpdHkgb2YgU8OjbyBQYXVsbyBjYW1wdXMgYW5kIGtlcHQgaW5kaXZpZHVhbGx5IGluIHBsYXN0aWMgZW5jbG9zdXJlcyAoMTcgeCAxOCB4IDEwNwpjbSkgZm9yIDUtNyBkYXlzIHByaW9yIHRvIGVzdGltYXRpbmcgd2F0ZXIgbG9zcy4gQW5pbWFscyB3ZXJlIGZlZCBjYXB0aXZlIGNvY2tyb2FjaGVzICgqTmF1cGhvZXRhIGNpbsOpcmVhKikgdHdpY2UgYSB3ZWVrIGFuZCB3ZXJlIHByb3ZpZGVkIGZyZXNoIHdhdGVyIGFkIGxpYml0dW0gKHRhcCB3YXRlcikgaW4gYSBwbGFzdGljIGN1cC4gVG8gZXN0aW1hdGUgZXZhcG9yYXRpdmUgd2F0ZXIgbG9zcywgZnVsbHkgaHlkcmF0ZWQgaW5kaXZpZHVhbHMgd2VyZSBicmllZmx5IGRyaWVkIHdpdGggYWJzb3JiZW50IHBhcGVyIGFuZCB0aGUgdXJpbmUgd2FzIHJlbW92ZWQgYnkgbGlnaHRseSBwcmVzc2luZyB0aGVpciBhYmRvbWVuIGFuZCB3ZWlnaGVkIHRvIG9idGFpbiB0aGUgaW5pdGlhbCB3ZWlnaHQuIEVhY2ggaW5kaXZpZHVhbCB3YXMgcGxhY2VkIGluIGEgd2luZCB0dW5uZWwgYXQgMjM1IGNtIHNeLTFeLCBhbmQgd2VpZ2hlZCBldmVyeSBmaXZlIG1pbnV0ZSB1bnRpbCBpbmRpdmlkdWFscyByZWFjaGVkIDkwJSBvZiB0aGVpciBpbml0aWFsIHdlaWdodCBvciB0aGUgYW5pbWFsIGRpZCBub3QgcmVnYWluIHBvc3R1cmUgd2hlbiB0dXJuZWQgb3Zlci4gRWFjaCBpbmRpdmlkdWFsIG1lYXN1cmVtZW50IHdhcyByZXBsaWNhdGVkIHR3aWNlIG92ZXIgdGhlICgzIGRheXMgaW4gYmV0d2VlbiBtZWFzdXJlbWVudHMpIGFuZCBhdmVyYWdlZC4gVGhlIHJhdGUgb2Ygd2F0ZXIgbG9zcyBmcm9tIHRoZSBhdmVyYWdlIHZhbHVlcyB3YXMgY2FsY3VsYXRlZCBhbmQgcHJlc2VudGVkIGFzIGluIG1nIGheLTFeLiBFdmFwb3JhdGl2ZSB3YXRlciBsb3NzIGNvcnJlY3RlZCBmb3Igc3VyZmFjZSBhcmVhIHdhcyBjYWxjdWxhdGVkIGJ5IGRpdmlkaW5nIGJ5IDIvMyBvZiB0aGUgdG90YWwgc3VyZmFjZSBhcmVhIHdoaWNoIGNvcnJlc3BvbmRzIHRvIHRoZSByZWdpb24gb2YgdGhlIGJvZHkgaW4gY29udGFjdCB3aXRoIHRoZSBhaXIgZmxvdyAobWcgY21eLTJeIG1pbl4tMV4pLiBUaGUgZXhwZXJpbWVudCB3YXMgY29uZHVjdGVkIGF0IGFuIGFpciB0ZW1wZXJhdHVyZSBiZXR3ZWVuIDIyLTI1wrBDIGF0IGEgcmVsYXRpdmUgaHVtaWRpdHkgb2YgNTAtNjAlLgoKRGF0YSBwcm92aWRlZCBieSBSLiBQYXJlbGxpIEJvdm8gKHJwYm92b0BnbWFpbC5jb20pIHdhcyBvcmlnaW5hbGx5IHVzZWQgZm9yIGEgc2VwYXJhdGUgcGFwZXIgd2hpY2ggaXMgY3VycmVudGx5IGluIGRldmVsb3BtZW50LiBIb3dldmVyLCBoZSBoYXMga2luZGx5IG9mZmVyZWQgdG8gcHJvdmlkZSB0aGUgZGF0YSBmb3IgdGhpcyBzdHVkeSBwcmUtc3VibWlzc2lvbi4gVGhlIHNwZWNpZXMgdGhhdCB3ZXJlIGNvbGxlY3RlZCBieSBSLiBQYXJlbGxpIEJvdm8gYXJlIHByb3ZpZGVkIGJlbG93OgoKLSAqQWRlbm9tZXJhIG1hcm1vcmF0YSoKLSAqQW1lZXJlZ2EgZmxhdm9waWN0YSoKLSAqQXBsYXN0b2Rpc2N1cyBsZXVjb3B5Z2l1cyoKLSAqQm9hbmEgcGFyZGFsaXMqCi0gKkJvYW5hIHJhbmljZXBzKgotICpCb2tlcm1hbm5vaHlsYSBhbHZhcmVuZ2FpKgotICpCb2tlcm1hbm5vaHlsYSBjaXJjdW1kYXRhKgotICpCb2tlcm1hbm5vaHlsYSBzYXhpY29sYSoKLSAqQnJhY2h5Y2VwaGFsdXMgcGl0YW5nYSoKLSAqRGVuZHJvcHNvcGh1cyBtaWNyb3BzKgotICpEZW5kcm9wc29waHVzIHNhbmJvcm5pKgotICpEZXJtYXRvbm90dXMgbXVlbGxlcmkqCi0gKkVsYWNoaXN0b2NsZWlzIGNlc2FyaWkqCi0gKkhhZGRhZHVzIGJpbm90YXR1cyoKLSAqSXNjaG5vY25lbWEgZ3VlbnRoZXJpKgotICpJc2Nobm9jbmVtYSBwYXJ2YSoKLSAqTGVwdG9kYWN0eWx1cyBmdXNjdXMqCi0gKkxlcHRvZGFjdHlsdXMgc3lwaGF4KgotICpPZG9udG9waHJ5bnVzIGFtZXJpY2FudXMqCi0gKlBoeWxsb21lZHVzYSBtZWdhY2VwaGFsYSoKLSAqUGh5c2FsYWVtdXMgYXRsYW50aWN1cyoKLSAqUGh5c2FsYWVtdXMgb2xmZXJzaWkqCi0gKlBpdGhlY29wdXMgYXp1cmVhZSoKLSAqUHJvY2VyYXRvcGhyeXMgYXBwZW5kaWN1bGF0YSoKLSAqUHJvY2VyYXRvcGhyeXMgY3VydXJ1KgotICpSaGluZWxsYSBkaXB0eWNoYSoKLSAqUmhpbmVsbGEgb3JuYXRhKgotICpSaGluZWxsYSBydWJlc2NlbnMqCi0gKlNjaW5heCBmdXNjb3Zhcml1cyoKLSAqVHJhY2h5Y2VwaGFsdXMgbWVzb3BoYWV1cyoKCkFkdWx0cyB3ZXJlIGNvbGxlY3RlZCBhbG9uZyBlbGV2YXRpb25hbCBncmFkaWVudHMgZnJvbSBzZWEgbGV2ZWwgdG8gMSw2MDAgbSBhLnMubCBpbiBCcmF6aWzigJlzIEF0bGFudGljIEZvcmVzdCBhbmQgQ2VycmFkbyBkdXJpbmcgd2FybS93ZXQgc2Vhc29ucyAoU2VwdGVtYmVyIHRvIEZlYnJ1YXJ5IG9mIDIwMTHigJMyMDE3KS4gQW5pbWFscyB3ZXJlIHRyYW5zcG9ydGVkIHRvIHRoZSBsYWJvcmF0b3J5ICg2MTMgbTogLTIyLjM5NzMzMcKwIFMsIDQ3LjU0Nzc5OcKwIFcpLiBBbGwgYW5pbWFscyB3ZXJlIGtlcHQgaW5kaXZpZHVhbGx5IGluIHBsYXN0aWMgdGVycmFyaWEsIHdpdGggc2hlbHRlciBhbmQgdGFwIHdhdGVyIGFkIGxpYml0dW0sIHVuZGVyIG5hdHVyYWwgdGhlcm1hbC9odW1pZGl0eSByZWdpbWVzIChkYWlseSB0ZW1wZXJhdHVyZSByYW5nZSBvZiAyMuKAkzI3IMKwQywgYWlyIGh1bWlkaXR5IG9mIDQ14oCTNjUlKSBhbmQgcGhvdG9wZXJpb2QgKGxpZ2h0L2RhcmsgY3ljbGVzIDEzLjU6MTAuNSkuCgpNZWFzdXJlbWVudHMgd2VyZSB0YWtlbiBvbmNlIGZvciBlYWNoIGluZGl2aWR1YWwsIGluIHRoZSBmb2xsb3dpbmcgc2VxdWVuY2U6IGV2YXBvcmF0aXZlIHdhdGVyIGxvc3MgKEVXTCkgYW5kIHdhdGVyIHVwdGFrZSAoV1UpIHdpdGhpbiAzLTUgZGF5cyBhZnRlciBmaWVsZCBjb2xsZWN0aW9uLiBBbmltYWxzIHdlcmUgbm90IGZlZCBhcyB0aGUgbWVhc3VybWVudHMgd2VyZSB0YWtlbiBpbiBhIGZhc3RlZCBzdGF0ZS4gQmVmb3JlIGFuZCBhZnRlciBhbnkgZXhwZXJpbWVudGFsIHJ1biwgYW5pbWFscyB3ZXJlIGNoZWNrZWQgZm9yIG1vdG9yIGNvb3JkaW5hdGlvbiwgc2tpbiBjb2xvciwgcG9zdHVyZSwgYW5kIHJlc3BvbnNpdmVuZXNzLiBXaGVuIGluZGl2aWR1YWxzIGZhaWxlZCB0aGVzZSBjaGVja3MsIHRoZXkgd2VyZSBub3QgaW5jbHVkZSBpbiB0aGUgZGF0YXNldCBhbmQgc3Vic2VxdWVudCBhbmFseXNlcy4KCkVXTCBhbmQgV1UgZXhwZXJpbWVudHMgd2VyZSBjb25kdWN0ZWQgZm9sbG93aW5nIEBBbmRlcnNvbjIwMTcsIEBHb3V2ZWlhMjAxOSwgYW5kIEBCb3ZvMjAyMy4gQnJpZWZseSwgYW5pbWFsc+KAmSB0ZW1wZXJhdHVyZSBhbmQgaHlkcmF0aW9uIHN0YXRlIHdlcmUgc3RhbmRhcmRpemVkIGJlZm9yZSB0aGUgdHJpYWxzIGJ5IGhvbGRpbmcgZWFjaCBhbXBoaWJpYW4gaW4gaW5kaXZpZHVhbCBQVkMgY29udGFpbmVycywgZmlsbGVkIHdpdGggMC41IGNtIChib2R5IHNpemVzIDwgNSBnKSBvciAxIGNtIG9mIHdhdGVyIChib2R5IHNpemVzID4gNSBnKSwgYW5kIHBsYWNlZCBpbnNpZGUgYSBjbGltYXRlLWNvbnRyb2xsZWQgaW5jdWJhdG9yICgxMjJGQyBtb2RlbCAtIEVsZXRyb2xhYikgYXQgMjUgwrBDIGZvciAxIGguIFRvIG9idGFpbiB0aGUgaW5pdGlhbCBzdGFuZGFyZGlzZWQgYm9keSBtYXNzICgxMDAlIGh5ZHJhdGVkKSwgZnJvZ3Mgd2VyZSBnZW50bHkgZHJpZWQgd2l0aCBhYnNvcmJlbnQgcGFwZXIgYW5kIHRoZWlyIGFiZG9tZW4gd2VyZSBsaWdodGx5IHByZXNzZWQgdG8gcmVtb3ZlIHVyaW5lIGZyb20gdGhlaXIgdXJpbmFyeSBibGFkZGVyLiBUaGVuLCBmcm9ncyB3ZXJlIGluZGl2aWR1YWxseSBwbGFjZWQgaW4gUFZDIGNvbnRhaW5lcnMgKDEsMDAwIG1sKSBhbmQgRVdMIHJhdGVzIHdlcmUgbWVhc3VyZWQgaW4gYSB0eXBpY2FsIG9wZW4tZmxvdyBzeXN0ZW0gYXQgMjUgwrBDLCBjb250YWluaW5nIGEgbWFzcyBmbG93IG1ldGVyIChTUy0zIFN1YnNhbXBsZXIsIFNhYmxlIFN5c3RlbXMpIHN1cHBseWluZyBhIHN0YWJsZSBhaXJmbG93IGF0IDIxLjY2IGNtXjNeIHNeLTFeICgxLDMwMCBtbCBtaW5eLTFeKSwgYSBSSC9EZXdwb2ludCBDb250cm9sbGVyIChERy00LCBTYWJsZSBTeXN0ZW1zKSBzdGFuZGFyZGl6aW5nIHRoZSBpbmN1cnJlbnQgcmVsYXRpdmUgaHVtaWRpdHkgYXQgMzAlLCBhbmQgYSB3YXRlciB2YXBvciBhbmFseXplciAoUkgtMzAwIFJIL0Rld3BvaW50IEFuYWx5emVyLCBTYWJsZSBTeXN0ZW1zKSBxdWFudGlmeWluZyBpbmN1cnJlbnQgYW5kIGV4Y3VycmVudCBhaXIuIEFsbCBlcXVpcG1lbnQgd2FzIGludGVyZmFjZWQgdG8gYSBjb21wdXRlciBieSBhbiBhbmFsb2cvZGlnaXRhbCB1bml0IChVSTIg4oCTIFNhYmxlIFN5c3RlbXMpIHRvIHJlY29yZCBjaGFuZ2VzIGluIGFpcmZsb3cgYW5kIHdhdGVyIHZhcG9yIGRlbnNpdHkgKFdWRCkgZXZlcnkgMS4wIHNlY29uZC4gU2tpbiBib2R5IHRlbXBlcmF0dXJlcyB3ZXJlIHRha2VuIGF0IHRoZSBlbmQgb2YgdGhlIGV4cGVyaW1lbnRzLCB0eXBpY2FsbHkgMzAtNDAgbWluIGZvciBmcm9ncyA8IDUgZyBhbmQgNjAgbWluIGZvciBmcm9ncyA+IDUgZywgZm9yIHF1YW50aWZpY2F0aW9uIG9mIHRoZSBXVkQgYXQgc2F0dXJhdGlvbiBhdCB0aGUgZXZhcG9yYXRpbmcgKHNraW4pIHN1cmZhY2UuIFRvIHF1YW50aWZ5IHRoZSBFV0wgcmF0ZXMsIHRoZSB3YXRlciB2YXBvciBkZW5zaXR5IGRlZmljaXQgd2FzIGNhbGN1bGF0ZWQgYnkgdGhlIGRpZmZlcmVuY2UgYmV0d2VlbiBhbiBlbXB0eSBjb250YWluZXIgYW5kIG9uZSBjb250YWluaW5nIHRoZSBhbmltYWwgKFNwb3RpbGEgYW5kIEJlcm1hbiAxOTc2KS4gVGhlbiwgdG90YWwgdHJhbnNlcGl0aGVsaWFsIEVXTCB3YXMgY29ycmVjdGVkIGZvciB1bml0IGFyZWEgb2YgZXhwb3NlZCBza2luIHN1cmZhY2UgKDIvMyBvZiB0aGUgdG90YWwgc3VyZmFjZTsgQE1jQ2xhbmFoYW4xOTY5KSBhbmQgZXhwcmVzc2VkIGFzIG1hc3Mgb2Ygd2F0ZXIgcGVyIGV4cG9zZWQgc3VyZmFjZSBhcmVhIHBlciB0aW1lIChlLmcuIM68ZyBIfjJ+TyBjbV7iiJIyXiBzXuKIkjFeKS4gVG8gbWluaW1pemUgdGhlIGFuaW1hbOKAmXMgYWN0aXZpdHkgZHVyaW5nIEVXTCBtZWFzdXJlbWVudHMsIGV4cGVyaW1lbnRzIHdlcmUgcGVyZm9ybWVkIGR1cmluZyB0aGUgZGF5IChvcHBvc2l0ZSB0byB0aGVpciBuYXR1cmFsIGFjdGl2ZSBwZXJpb2QpIHdpdGggY2hhbWJlcnMgaW4gdGhlIGRhcmsuIFRvIGRldGVjdCBhbnkgc2lnbmlmaWNhbnQgY2hhbmdlcyBpbiBiZWhhdmlvciBhbmQgcG9zdHVyZSB0aGF0IGNvdWxkIGFmZmVjdCB0aGUgcmVjb3JkcywgaW5kaXZpZHVhbHMgd2VyZSBvZnRlbiB2aXN1YWxseSBpbnNwZWN0ZWQgZHVyaW5nIHRyaWFscy4gRGF0YSB3ZXJlIGRpc2NhcmRlZCBpZiBhbiBhbmltYWwgdXJpbmF0ZWQgZHVyaW5nIHRoZSBleHBlcmltZW50LgoKSW1tZWRpYXRlbHkgYWZ0ZXIgdGhlIEVXTCB0cmlhbHMsIHdoZXJlIGFuaW1hbHMgdXN1YWxseSBsb3N0IDk4LTcwICUgb2YgdGhlaXIgaW5pdGlhbCBib2R5IG1hc3NlcyAoc2VlIGRhdGFzZXQpLCBlYWNoIGluZGl2aWR1YWwgd2FzIHBsYWNlZCBpbiBhIGNvbnRhaW5lciAoYSBQZXRyaSBkaXNoIGZvciBib2R5IHNpemVzIHNtYWxsZXIgdGhhbiA1IGcsIG9yIGEgY2lyY3VsYXIgUFZDIGNvbnRhaW5lciBmb3IgYm9keSBzaXplcyBsYXJnZXIgdGhhbiA1IGcpIGZpbGxlZCB3aXRoIHRhcCB3YXRlciBhdCBhIGRlcHRoIHN1ZmZpY2llbnQgdG8gY292ZXIgdGhlaXIgdmVudHJhbCByZWdpb24uIEFuaW1hbHMgd2VyZSB0YWtlbiBmcm9tIHRoZSBjb250YWluZXIgYW5kIGNhcmVmdWxseSBibG90dGVkIHdpdGggcGFwZXIgdGlzc3VlIGFuZCB3ZWlnaGVkICjCsSAwLjAwMDEgZyBvciAwLjAxIGcpIGV2ZXJ5IDIgbWludXRlcyBmb3Igc2l4IGNvbnNlY3V0aXZlIHRpbWVzIGluIGEgcm9vbSBhdCAyNSDCsEMuIFdVIHJhdGVzIHdlcmUgY2FsY3VsYXRlZCBmcm9tIHRoZSBsaW5lYXIgcmVncmVzc2lvbiBiZXR3ZWVuIGJvZHkgbWFzcyBpbmNyZW1lbnRzIGFnYWluc3QgdGltZS4gVGhlbiwgdXNpbmcgdGhlIGVzdGltYXRlZCBzdXJmYWNlIGFyZWEgaW4gY29udGFjdCB3aXRoIHdhdGVyICgxLzMgb2YgdGhlIHRvdGFsIHN1cmZhY2UsIEBNY0NsYW5haGFuMTk2OSksIHRoZSBXVSByYXRlIHdhcyBjYWxjdWxhdGVkIGFuZCBleHByZXNzZWQgcGVyIHVuaXQgYXJlYSAoZS5nLiDOvGcgSH4yfk8gY21e4oiSMl4gc17iiJIxXikuCgpEYXRhIGZvciAqQnJldmljZXBzIG1vbnRhbnVzKiBwcm92aWRlZCBieSBTLiBDbHVzZWxsYS1UcnVsbGFzIChzY3QzMzNAc3VuLmFjLnphKSBpcyB1c2VkIGZvciBhIG1hbnVzY3JpcHQgdGhhdCBpcyBjdXJyZW50bHkgaW4gc3VibWlzc2lvbi4gSG93ZXZlciwgc2hlIGhhcyBraW5kbHkgb2ZmZXJlZCB0byBwcm92aWRlIHRoZSBkYXRhIGZvciB0aGlzIHN0dWR5IHByZS1zdWJtaXNzaW9uLgoKVGhlIHJhdyBkYXRhLCBpbmNsdWRpbmcgY29sbGVjdGlvbiBzaXRlcywgYXJlIHByb3ZpZGVkIG9uIFtHaXRIdWJdKGh0dHBzOi8vZ2l0aHViLmNvbS9uaWNob2xhc3d1bnovZ2xvYmFsLWZyb2ctZHJvdWdodC90cmVlL21haW4vZGF0YSkuCgoqKioKCiMjIENhbGN1bGF0aW9ucyBhbmQgY29udmVyc2lvbnMgey19CgojIyMgRXZhcG9yYXRpdmUgd2F0ZXIgbG9zcyB7LX0KVGhlIHJlbGF0aXZlIHNraW4gcmVzaXN0YW5jZSwgJHJfaSQsIGlzIGNhbGN1bGF0ZWQgYXM6IAoKXGJlZ2lue2VxdWF0aW9ufQpyX2kgPSByX3QgLSByX2IsCihcI2VxOnJlc3QpClxlbmR7ZXF1YXRpb259Cgp3aGVyZSAkcl90JCBpcyB0aGUgdG90YWwgcmVzaXN0YW5jZSAocyBjbV4tMV4pIGFuZCAkcl9iJCBpcyB0aGUgYm91bmRhcnkgbGF5ZXIgcmVzaXN0YW5jZSBiYXNlZCBvbiBhbiBlcXVpdmFsZW50IGFnYXIgbW9kZWwgKHMgY21eLTFeKSBvciBoeXBvdGhldGljYWwgYmlvcGh5c2ljYWwgbW9kZWwgXEByZWYoZXE6cmIpLiAkcl90JCBpcyBjYWxjdWxhdGVkIGZvbGxvd2luZyBAU3BvdGlsYTE5NzYgYW5kIEBIaWxsbWFuMjAwOToKClxiZWdpbntlcXVhdGlvbn0Kcl90ID0gXGZyYWN7XHJob317XHRleHRybXtDV0x9fSA9IChccmhvX3t2W3NraW5dfSAtIFxyaG9fdiBcdGltZXMgXHRleHRybXtSSH1fe1tleGN1cnJlbnRdfSkgXHRpbWVzIFx0ZXh0cm17Q1dMfSwKKFwjZXE6dHJlc3QpClxlbmR7ZXF1YXRpb259Cgp3aGVyZSAkXHJobyQgaXMgdGhlIHZhcG91ciBkZW5zaXR5IGdyYWRpZW50IGF0IHRoZSBzdXJmYWNlIG9mIHRoZSBhbmltYWwgKGcgY21eLTNeKSwgJFx0ZXh0cm17Q1dMfSQgaXMgdGhlIGN1dGFuZW91cyByYXRlcyBvZiBldmFwb3JhdGl2ZSB3YXRlciBsb3NzICgkXHRleHRybXtFV0x9JCkgYnkgc3VyZmFjZSBhcmVhIChnIHNeLTFeIGNtXi0yXiksICRccmhvX3YkIGlzIHRoZSB3YXRlciB2YXBvdXIgZGVuc2l0eSBvZiB3YXRlci1zYXR1cmF0ZWQgYWlyIChnIGNtXi0zXiksICRccmhvX3t2W3NraW5dfSQgaXMgdGhlICRccmhvX3YkIGF0IHRoZSBza2luIHN1cmZhY2UsIGFuZCAkXHRleHRybXtSSH0kIGlzIHRoZSBmcmFjdGlvbmFsIHNhdHVyYXRpb24gKDAtMSkuICRccmhvJCBpcyBjYWxjdWxhdGVkIGFzIHRoZSBkaWZmZXJlbmNlIGluIHRoZSB3YXRlciB2YXBvdXIgZGVuc2l0eSBhdCB0aGUgdGVtcGVyYXR1cmUgb2YgdGhlIGV2YXBvcmF0aW5nIHN1cmZhY2UgYnkgdGhlIHdhdGVyIHZhcG91ciBkZW5zaXR5IGluIHRoZSBhaXIgYXQgJFx0ZXh0cm17Ukh9JCBhcyBmcmFjdGlvbmFsIHNhdHVyYXRpb24gW0BGZWRlcjE5OTJdLgoKJFx0ZXh0cm17RVdMfSQgKGcgc14tMV4pIGNhbiBiZSBtZWFzdXJlZCBncmF2aW1ldHJpY2FsbHkgKGNoYW5nZSBpbiBtYXNzIG92ZXIgdGltZSkgb3IgY2hhbmdlcyBpbiB3YXRlciB2YXBvdXIgcHJlc3N1cmUsICRlJCAoa1BhKSwgb3IgJFx0ZXh0cm17Ukh9JCBiZXR3ZWVuIHRoZSBpbmN1cnJlbnQgYW5kIGV4Y3VycmVudCBhaXIgZm9yIGEgZmxvdy10aHJvdWdoIHN5c3RlbS4gSW4gYSBmbG93LXRocm91Z2ggc3lzdGVtLCAkXHRleHRybXtFV0x9JCBjYW4gYmUgY2FsY3VsYXRlZCBmcm9tIEBIaWxsbWFuMjAwOSBhbmQgQFJpZGRlbGwyMDE3OgoKXGJlZ2lue2VxdWF0aW9ufQpcdGV4dHJte0VXTH0gPSBcZnJhY3tlfXtUIFx0aW1lcyBSX3Z9IFx0aW1lcyBcdGV4dHJte0ZSfSA9IFsoXHJob192IFx0aW1lcyBcdGV4dHJte1JIfV97W2luY3VycmVudF19KSAtIChccmhvX3YgXHRpbWVzIFx0ZXh0cm17Ukh9X3tbZXhjdXJyZW50XX0pXSBcdGltZXMgXHRleHRybXtGUn0sCihcI2VxOmV3bCkKXGVuZHtlcXVhdGlvbn0KCndoZXJlICRUJCBpcyB0ZW1wZXJhdHVyZSBpbiBLZWx2aW4gKEspLCAgJFJfdiQgaXMgdGhlIGdhcyBjb25zdGFudCBmb3Igd2F0ZXIgdmFwb3IgKDQ2MS41IEogS14tMV4ga2deLTFeKSwgYW5kICRcdGV4dHJte0ZSfSQgaXMgdGhlIGZsb3cgcmF0ZSAobWwgc14tMV4pCgojIyMgQm91bmRhcnkgbGF5ZXIgcmVzaXN0YW5jZSB7LX0KVGhlIGJvdW5kYXJ5IGxheWVyIHJlc2lzdGFuY2UgaXMgdGhlIGxheWVyIG9mIGFpciBpbiB3aGljaCBhbiBvYmplY3QgKG9yIG9yZ2FuaXNtKSBleGNoYW5nZXMgaGVhdCBhbmQgbWFzcyB3aXRoIGl0cyBzdXJyb3VuZGluZyBlbnZpcm9ubWVudC4gVGhlIGJvdW5kYXJ5IGxheWVyIGFkZHMgdG8gdGhlIHJlc2lzdGFuY2Ugb2Ygd2F0ZXIgbG9zcyBieSBjaGFuZ2luZyB0aGUgcGh5c2ljYWwgY29uZGl0aW9ucyBvZiB0aGUgbWljcm9jbGltYXRlIGFyb3VuZCB0aGUgb3JnYW5pc20gW0BTZW56YW5vMjAyMl0uIElmICRyX2IkIHdhcyBub3QgcmVwb3J0ZWQgb3Igbm90IGVzdGltYXRlZCBieSBhIHJlcHJlc2VudGF0aXZlIGFnYXIgbW9kZWwsIHdlIHVzZWQgdGhlIHRoZW9yZXRpY2FsICRyX2IkIHdpdGgga25vd24gZm9yY2VkIGNvbnZlY3Rpb24gKCRWJCkgZnJvbSBAUmlkZGVsbDIwMTc6IAoKXGJlZ2lue2VxdWF0aW9ufQpyX2IgPSBcZnJhY3swLjkzIFx0aW1lcyBccmhvIFx0aW1lcyBDX3tccmhvfX17aF9jfSwKKFwjZXE6cmIpClxlbmR7ZXF1YXRpb259Cgp3aGVyZSwgJFxyaG8kICBpcyB0aGUgZGVuc2l0eSBvZiB0aGUgYWlyIChrZyBtXi0zXiksICRDX3tccmhvfSQgaXMgdGhlIHNwZWNpZmljIGhlYXQgb2YgYWlyIChrZ14tMV4gS14tMV4pIGNhbGN1bGF0ZWQgYXM6CgpcYmVnaW57ZXF1YXRpb259CkNfe1xyaG99ID0gXGZyYWN7MTAwNC44NCArICgxODQ2LjQwIFx0aW1lcyByX3cpfXsxICsgcl93fSwKKFwjZXE6Y3ApClxlbmR7ZXF1YXRpb259Cgp3aGVyZSAkcl93JCBpcyBtaXhpbmcgcmF0aW8gb2Ygd2F0ZXIgdmFwb3VyIFtAVHJhY3kyMDE5XSBlc3RpbWF0ZWQgdXNpbmc6CgpcYmVnaW57ZXF1YXRpb259CnJfdyA9IFxmcmFjezAuNjIxOTcgXHRpbWVzIDEuMDA1MyBcdGltZXMgZX17cCAtIDEuMDA1MyBcdGltZXMgZX0sCihcI2VxOnJ3KQpcZW5ke2VxdWF0aW9ufQoKd2hlcmUgJGUkIGlzIHRoZSB2YXBvdXIgcHJlc3N1cmUgKGtQYSkgYW5kICRwJCBpcyB0aGUgYXRtb3NwaGVyaWMgcHJlc3N1cmUgKGtQYSkuICRoX2MkIFxAcmVmKGVxOnJiKSBpcyB0aGUgY29lZmZpY2llbnQgb2YgY29udmVjdGl2ZS1oZWF0IHRyYW5zZmVyIHVuZGVyIGZvcmNlZCBjb252ZWN0aW9uIGFwcHJveGltYXRlZCBieToKClxiZWdpbntlcXVhdGlvbn0KaF9jID0gMC4wOTIzKFZeezAuMDMzM30gXHRpbWVzIEReey0wLjY2Nn0pLAooXCNlcTpoYykKXGVuZHtlcXVhdGlvbn0KCndoZXJlICRWJCBpcyB0aGUgd2luZCBzcGVlZCAobSBzXi0xXikgYW5kICREJCBpcyB0aGUgY2hhcmFjdGVyaXN0aWMgZGltZW5zaW9uIChtKS4gJEQkIGlzIHRoZSBjcm9zcy1zZWN0aW9uYWwgcmFkaXVzLCBhc3N1bWluZyB0aGUgZGltZW5zaW9ucyBvZiBhIHNwaGVyZSBmb3IgYSBmcm9nLCBiYXNlZCBvbiB0aGUgbWFzcyBhbmQgdGhlIHRvdGFsIHN1cmZhY2UgYXJlYS4KCklmIHRoZSBzdHVkeSB3YXMgY29uZHVjdGVkIHVuZGVyIGZyZWUgY29udmVjdGlvbiwgd2UgdXNlZCBhIG1vZGlmaWVkIFxAcmVmKGVxOmhjKSBmcm9tIEBSaWRkZWxsMjAxNzoKClxiZWdpbntlcXVhdGlvbn0KaF9jID0gXGZyYWN7MC40OCBcdGltZXMgXHRleHRybXtHcn1eezAuMjV9IFx0aW1lcyBrfXtEfSwKKFwjZXE6aGNmcmVlKQpcZW5ke2VxdWF0aW9ufQoKd2hlcmUgJFx0ZXh0cm17R3J9JCBpcyB0aGUgR3Jhc2hvZiBudW1iZXIsICRrJCBpcyB0aGUgdGhlcm1hbCBjb25kdWN0aXZpdHkgb2YgdGhlIGZsdWlkIChXIG1eLTFeIEteLTFeKSAkRCQgaXMgdGhlIGNoYXJhY3RlcmlzdGljIGRpbWVuc2lvbiAobSkuICRcdGV4dHJte0dyfSQgZGVzY3JpYmVzIHRoZSByZWxhdGl2ZSBzdHJlbmd0aCBvZiB0aGUgYnVveWFudCBmb3JjZXMgdG8gdmlzY291cyBmb3JjZSBvZiB0aGUgYWlyIHN1cnJvdW5kaW5nIHRoZSBvYmplY3QgY2FsY3VsYXRlZCBhczoKClxiZWdpbntlcXVhdGlvbn0KXHRleHRybXtHcn0gPSBcZnJhY3tnIFx0aW1lcyBcYmV0YSBcdGltZXMgXERlbHRhe1R9IFx0aW1lcyBEXnszfX17dl57Mn19LAooXCNlcTpncikKXGVuZHtlcXVhdGlvbn0KCndoZXJlICRnJCBpcyB0aGUgYWNjZWxlcmF0aW9uIGJ5IGdyYXZpdHkgKDkuODAgbSBzXi0yXiksICRcYmV0YSQgaXMgdGhlIGNvZWZmaWNpZW50IG9mIHZvbHVtZXRyaWMgZXhwYW5zaW9uICgzLjY3ICRcdGltZXMkIDEwXi0zXiDCsENeLTFeKSwgJEQkIGlzIHRoZSBjaGFyYWN0ZXJpc3RpYyBkaW1lbnNpb24sICR2JCBpcyB0aGUga2luZW1hdGljIHZpc2Nvc2l0eSBmcm9tIEBSaWRkZWxsMjAxNywgYW5kICRcRGVsdGF7VH0kIGlzIGVzdGltYXRlZCBieToKClxiZWdpbntlcXVhdGlvbn0KXERlbHRhe1R9ID0gVF8wKDErMC4zOCBcdGltZXMgZV8wIC8gcCkgLSBUKDErMC4zOCBcdGltZXMgZS9wKSwKKFwjZXE6ZGVsdGEpClxlbmR7ZXF1YXRpb259Cgp3aGVyZSAkVF8wJCBpcyB0aGUgdGVtcGVyYXR1cmUgKEspIG9mIHRoZSBzdXJmYWNlLCAkZV8wJCBpcyB0aGUgd2F0ZXIgdmFwb3VyIHByZXNzdXJlIGRpcmVjdGx5IGFib3ZlIHRoZSBzdXJmYWNlLCBhbmQgJHAkIGlzIHRoZSBhdG1vc3BoZXJpYyBwcmVzc3VyZSBbQE1vbnRpZXRoMjAxM10uIAoKIyMjIFZhcG91ciBwcmVzc3VyZSBkZWZpY2l0IHstfQoKVGhlIHZhcG91ciBwcmVzc3VyZSBkZWZpY2l0IHdhcyBjYWxjdWxhdGVkIGFzOgoKXGJlZ2lue2VxdWF0aW9ufQpWUEQgPSBlX3MgLSBlX2EsCihcI2VxOnZwZCkKXGVuZHtlcXVhdGlvbn0KCndoZXJlICRlX3MkIGlzIHRoZSBzYXR1cmF0aW9uIHZhcG91ciBwcmVzc3VyZSAoa1BhKSBhdCBhIGdpdmVuIHRlbXBlcmF0dXJlIGFuZCAkZV9hJCBpcyB0aGUgYWN0dWFsIHZhcG91ciBwcmVzc3VyZSBpbiB0aGUgYWlyIChrUGEpLiAkZV9zJCB3YXMgY2FsY3VsYXRlZCB1c2luZyB0aGUgQ2xhdXNpdXMtQ2xhcGV5cm9uIGVxdWF0aW9uIEBTdHVsbDIwMDA6CgpcYmVnaW57ZXF1YXRpb259CmVfcyA9IGVfMCBcdGltZXMgXGV4cCBcbGVmdFtcZnJhY3tMfXtSX3Z9IFxsZWZ0KCBcZnJhY3sxfXtUXzB9IC0gXGZyYWN7MX17VH0gXHJpZ2h0KSBccmlnaHRdLAooXCNlcTplcykKXGVuZHtlcXVhdGlvbn0KCndoZXJlICRlXzAkID0gMC42MTEga1BhIGFuZCAkVF8wJCDigJMgMjczIEsgYXJlIGNvbnN0YW50IHBhcmFtZXRlcnMsIGFuZCAkUl92JCDigJMgNDYxLjUgSiBLXi0xXiBLZ14tMV4gYW5kICRMJCA9IDIuNSB4IDEwNiBKIGtnXi0xXiBhcmUgZ2FzIGNvbnN0YW50IGZvciB3YXRlciB2YXBvdXIgYW5kIHRoZSBsYXRlbnQgaGVhdCBvZiB2YXBvdXJpemF0aW9uLCByZXNwZWN0aXZlbHkuICAkVCQgKGFzIEspIGlzIHRoZSBhY3R1YWwgdGVtcGVyYXR1cmUgbWVhc3VyZWQuICRlX2EkIHdhcyBhcHByb3hpbWF0ZWQgYXM6CgpcYmVnaW57ZXF1YXRpb259CmVfYSA9IFxmcmFje1x0ZXh0cm17Ukh9IFx0aW1lcyBlX3N9ezEwMH0sCihcI2VxOmVhKQpcZW5ke2VxdWF0aW9ufQoKd2hlcmUgJFx0ZXh0cm17Ukh9JCBpcyB0aGUgbWVhc3VyZWQgcmVsYXRpdmUgaHVtaWRpdHkgKCUpLgoKIyMjIFN1cmZhY2UgYXJlYSB7LX0KCkZvciBzdHVkaWVzIHRoYXQgcHJlc2VudGVkIEVXTCBhbmQgV1Ugd2l0aG91dCBjb3JyZWN0aW5nIGZvciBzdXJmYWNlIGFyZWEsIHdlIGNvcnJlY3RlZCB0byBzdXJmYWNlIGFyZWEgYnkgZGl2aWRpbmcgdGhlIGFic29sdXRlIHJhdGVzIGJ5IDIvMyBvZiB0aGUgdG90YWwgc3VyZmFjZSBhcmVhIGZvciBFV0wsIHdoaWNoIGNvcnJlc3BvbmRzIHRvIHRoZSBhcmVhIGV4cG9zZWQgdG8gYWlyIHdoZW4gYW51cmFucyBrZWVwIHRoZSB3YXRlciBjb25zZXJ2YXRpb24gcG9zdHVyZSBbQFdpdGhlcnMxOTgyOyBAV2l0aGVyczE5ODRdLiBGb3IgV1UsIHdlIGNvcnJlY3RlZCB0byBzdXJmYWNlIGFyZWEgYnkgZGl2aWRpbmcgdGhlIGFic29sdXRlIHJhdGVzIGJ5IDEvMyBvZiB0aGUgdG90YWwgc3VyZmFjZSBhcmVhIGJlY2F1c2UgV1UgcHJpbWFyaWx5IG9jY3VycyBpbiB0aGUgcGVsdmljICdzZWF0IHBhdGNoJyByZWdpb24gb2YgdGhlIHZlbnRyYWwgc2tpbiBbQEJhbGR3aW4xOTc0OyBATWNDbGFuYWhhbjE5Njk7IEBXaWxsdW1zZW4yMDA3XS4gVG90YWwgc3VyZmFjZSBhcmVhIChjbV4yXikgd2FzIGVzdGltYXRlZCB2aWEgZmFtaWx5LXNwZWNpZmljIG1hc3Mtc3VyZmFjZSBhcmVhIHNjYWxpbmcgcmVsYXRpb25zaGlwIGZyb20gQEtsZWluMjAxNjoKClxiZWdpbntlcXVhdGlvbn0KU0EgPSBcYmV0YV8wIE1ee1xiZXRhXzF9LAooXCNlcTpzYSkKXGVuZHtlcXVhdGlvbn0KCndoZXJlICRcYmV0YV8wJCBpcyB0aGUgaW50ZXJjZXB0LCAkTSQgaXMgdGhlIGFuaW1hbCBib2R5IG1hc3MgKGcpLCBhbmQgJFxiZXRhXzEkIGlzIHRoZSBzbG9wZS4gSWYgdGhlIGZhbWlseS1zcGVjaWZpYyBtYXNzLXN1cmZhY2UgYXJlYSBzY2FsaW5nIHJlbGF0aW9uc2hpcCB3YXMgbm90IHByZXNlbnRlZCwgd2UgdXNlZCB0aGUgcG93ZXIgZXF1YXRpb24gZm9yIGFsbCBBbnVyYSAoOS44NTM3JE0kXjAuNjc0NV4pIGFzIGEgY29uc2VydmF0aXZlIGVzdGltYXRlLgoKIyMjIFBlcmNlbnRhZ2UgbWFzcyBjaGFuZ2UgdG8gYWN0dWFsIG1hc3MgY2hhbmdlIHstfQoKRm9yIHN0dWRpZXMgdGhhdCBwcmVzZW50ZWQgJSBjaGFuZ2UgaW4gbWFzcyAoJFxEZWx0YSBNJCkgd2l0aCByYXcgZGF0YSBhdmFpbGFibGUgb24gaW5pdGlhbCBtYXNzLCB3ZSBjb252ZXJ0ZWQgcGVyY2VudGFnZSBjaGFuZ2UgaW4gbWFzcyAoJSBoXi0xXikgYmFjayB0byBhY3R1YWwgbWFzcyBjaGFuZ2UgKGcgaF4tMV4pIGZvbGxvd2luZzogCgpcYmVnaW57ZXF1YXRpb259Clx0ZXh0cm17RVdMfSA9IE0gXHRpbWVzIFxsZWZ0KFxmcmFje1xEZWx0YSBNfXsxMDB9XHJpZ2h0KSwKKFwjZXE6ZXdscGVyKQpcZW5ke2VxdWF0aW9ufQoKd2hlcmUgJE0kIGlzIHRoZSBpbml0aWFsIGJvZHkgbWFzcyAoZyksIGFuZCAkXERlbHRhIE0kIGlzIHRoZSBwZXJjZW50YWdlIGNoYW5nZSBpbiBtYXNzICglIGheLTFeKS4gTm90ZSwgc3R1ZGllcyB3aXRoICUgY2hhbmdlIGluIGJvZHkgbWFzcyB3aXRob3V0IHRoZSBpbml0aWFsIGJvZHkgbWFzcyBwcmVzZW50ZWQgd2VyZSBub3QgaW5jbHVkZWQuCgoqKioKCiMgRGF0YXNldCB7LX0KCmBgYHtyIGNsZWFuLCBtZXNzYWdlPUZBTFNFfQojIExvYWQgYW5kIGNsZWFuIHJhdyBkYXRhCnJhd19kYXQgPC0gcmVhZC5jc3YoZmlsZS5wYXRoKGRhdGFfcGF0aCwgInJhd19kYXRhLmNzdiIpKSAlPiUKICBkcGx5cjo6c2VsZWN0KHN0dWR5X0lEOnVuaXQpICU+JQogIGRwbHlyOjptdXRhdGUoZWNvdHlwZSAgPSBmYWN0b3IoZWNvdHlwZSksCiAgICAgICAgIGZhbWlseSAgID0gZmFjdG9yKGZhbWlseSksCiAgICAgICAgIG9yaWdpbiAgID0gZmFjdG9yKG9yaWdpbiksCiAgICAgICAgIHN0cmF0ZWd5ID0gZmFjdG9yKGNhc2Vfd2hlbihzdHJhdGVneSA9PSAiIiB+ICJub25lIiwgVFJVRSB+IGFzLmNoYXJhY3RlcihzdHJhdGVneSkpKSwKICAgICAgICAgc3RyYXRlZ3kgPSBmY3RfcmVsZXZlbChzdHJhdGVneSwgIm5vbmUiLCAid2F0ZXItcHJvb2YiLCAiY29jb29uIiwgImhvbGxvdyIpLAogICAgICAgICB0cmFpdCAgICA9IGZhY3Rvcih0cmFpdCksCiAgICAgICAgIHJlc3BvbnNlID0gZmFjdG9yKHJlc3BvbnNlKSwKICAgICAgICAgbG5NYXNzICAgPSBsb2cobWVhbl9tYXNzX2cpLAogICAgICAgICBsbkZsb3cgICA9IGxvZyhhaXJmbG93X2NtX3MgKyAxKSwKICAgICAgICAgZXNfa1BhICAgPSBpZmVsc2UodHJhaXQgPT0gIndhdGVyIGxvc3MiLCAwLjYxMSAqIGV4cCgyNTAwMDAwIC8gNDYxLjUgKiAoMSAvIDI3MyAtIDEgLyAodHJ0X3RlbXAgKyAyNzMuMTUpKSksIE5BKSwgIyBzYXR1cmF0aW9uIHZhcG9yIHByZXNzdXJlIChrUGEpIGF0IGEgZ2l2ZW4gdGVtcGVyYXR1cmUKICAgICAgICAgZWFfa1BhICAgPSBpZmVsc2UodHJhaXQgPT0gIndhdGVyIGxvc3MiLCBSSF9wZXJjICogZXNfa1BhIC8gMTAwLCBOQSksICMgYWN0dWFsIHZhcG9yIHByZXNzdXJlIChrUGEpCiAgICAgICAgIFZQRF9rUGEgID0gZXNfa1BhIC0gZWFfa1BhLAogICAgICAgICBsblZQRCAgICA9IGxvZyhWUERfa1BhKSkgJT4lCiAgZHBseXI6OmZpbHRlcihzcGVjaWVzX3BoeWxvICE9ICIiKSAjIHJlbW92ZSByb3dzIHdpdGggbm8gc3BlY2llcwoKZXdsX2RhdCA8LSByYXdfZGF0ICU+JQogIGRwbHlyOjpmaWx0ZXIocmVzcG9uc2UgPT0gImV2YXBvcmF0aXZlIHdhdGVyIGxvc3MiICYgIWlzLm5hKHVuaXRfY29ycmVjdGVkX21lYW4pKSAlPiUKICBkcGx5cjo6bXV0YXRlKG1nX2hfbWVhbiA9IHVuaXRfY29ycmVjdGVkX21lYW4gKiBkb3JzX1NBX2NtMiwKICAgICAgICAgICAgICAgIG1nX2hfc2QgICA9IHVuaXRfY29ycmVjdGVkX3NkICogZG9yc19TQV9jbTIsICAgIAogICAgICAgICAgICAgICAgbG5NZWFuICAgID0gbG9nKG1nX2hfbWVhbiksCiAgICAgICAgICAgICAgICB2ICAgICAgICAgPSBtZ19oX3NkXjIgLyBzYW1wbGVfc2l6ZSwgIyBzYW1wbGluZyB2YXJpYW5jZSAodikKICAgICAgICAgICAgICAgIHNlaSAgICAgICA9IHNxcnQodiksICMgc3RhbmRhcmQgZXJyb3IgKFNFKQogICAgICAgICAgICAgICAgaW52ICAgICAgID0gMSAvIHNlaSwgIyBwcmVjaXNpb24gKGludmVyc2Ugb2YgU0UpICkKICAgICAgICAgICAgICAgIHcgICAgICAgICA9IDEgLyB2LCAjIHdlaWdodCAoaW52ZXJzZSBvZiB2YXJpYW5jZSkgCiAgICAgICAgICAgICAgICBoXzcwICAgICAgPSAobWVhbl9tYXNzX2cgLSAobWVhbl9tYXNzX2cgKiAwLjcpKSAvIChtZ19oX21lYW4gKiAwLjAwMSkpIAoKcmVzaXN0X2RhdCA8LSByYXdfZGF0ICU+JQogIGRwbHlyOjpmaWx0ZXIodW5pdCA9PSAicyBjbSIgJiAhaXMubmEodW5pdF9jb3JyZWN0ZWRfbWVhbikpCgp3dV9kYXQgPC0gcmF3X2RhdCAlPiUKICBkcGx5cjo6ZmlsdGVyKHJlc3BvbnNlID09ICJ3YXRlciB1cHRha2UiICYgIWlzLm5hKHVuaXRfY29ycmVjdGVkX21lYW4pKSAlPiUKICBkcGx5cjo6bXV0YXRlKG1nX2hfbWVhbiA9IHVuaXRfY29ycmVjdGVkX21lYW4gKiB2ZW50X1NBX2NtMiwKICAgICAgICAgICAgICAgIG1nX2hfc2QgICA9IHVuaXRfY29ycmVjdGVkX3NkICogdmVudF9TQV9jbTIsCiAgICAgICAgICAgICAgICBsbk1lYW4gICAgPSBsb2cobWdfaF9tZWFuKSwKICAgICAgICAgICAgICAgIHYgICAgICAgICA9IG1nX2hfc2ReMiAvIHNhbXBsZV9zaXplLCAjIHNhbXBsaW5nIHZhcmlhbmNlICh2KQogICAgICAgICAgICAgICAgc2VpICAgICAgID0gc3FydCh2KSwgIyBzdGFuZGFyZCBlcnJvciAoU0UpCiAgICAgICAgICAgICAgICBpbnYgICAgICAgPSAxIC8gc2VpKSAjIHByZWNpc2lvbiAoaW52ZXJzZSBvZiBTRSkKCiNld2xfZGF0ICU+JQogICNncm91cF9ieShzdHJhdGVneSkgJT4lCiAgI3N1bW1hcmlzZShtZWFuID0gbWVhbihoXzcwLCBuYS5ybSA9IFRSVUUpKQpgYGAKClRoZXJlIGFyZSBgciBsZW5ndGgodW5pcXVlKGV3bF9kYXQkc3BlY2llc19waHlsbykpYCBzcGVjaWVzIHdpdGggZGF0YSBvbiBldmFwb3JhdGl2ZSB3YXRlciBsb3NzIChgciBsZW5ndGgodW5pcXVlKGV3bF9kYXQkc3R1ZHlfSUQpKWAgc3R1ZGllcyksIGByIGxlbmd0aCh1bmlxdWUocmVzaXN0X2RhdCRzcGVjaWVzX3BoeWxvKSlgIHNwZWNpZXMgd2l0aCBza2luIHJlc2lzdGFuY2UgZGF0YSAoYHIgbGVuZ3RoKHVuaXF1ZShyZXNpc3RfZGF0JHN0dWR5X0lEKSlgIHN0dWRpZXMpLCBhbmQgYHIgbGVuZ3RoKHVuaXF1ZSh3dV9kYXQkc3BlY2llc19waHlsbykpYCBzcGVjaWVzIHdpdGggd2F0ZXIgdXB0YWtlIGRhdGEgKGByIGxlbmd0aCh1bmlxdWUod3VfZGF0JHN0dWR5X0lEKSlgIHN0dWRpZXMpLiBXZSB1c2VkIHRoZSBldmFwb3JhdGl2ZSB3YXRlciBsb3NzIHRvIGFuYWx5c2UgZGlmZmVyZW5jZXMgYmV0d2VlbiBlY290eXBlIGFzIHRoZXJlIGFyZSBtb3JlIHNwZWNpZXMgcmVwcmVzZW50ZWQgY29tcGFyZWQgdG8gdGhlIHNraW4gcmVzaXN0YW5jZSBkYXRhLiBUaGVyZSB3ZXJlIHRocmVlIHNwZWNpZXMgdGhhdCB3ZXJlIGV4Y2x1ZGVkIGZyb20gdGhlIGFuYWx5c2lzIGJlY2F1c2UgdGhleSB3ZXJlIG5vdCBsaXN0ZWQgaW4gdGhlIElVQ04gUmVkIExpc3QgYW5kIHdlcmUgbm90IHByZXNlbnQgaW4gdGhlIHBoeWxvZ2VuZXRpYyB0cmVlIGZyb20gQEpldHoyMDE4OiAqQnJhY2h5Y2VwaGFsdXMgcGl0YW5nYSosICpFbGFjaGlzdG9jbGVpcyBjZXNhcmlpKiwgYW5kICpMZXB0b2RhY3R5bHVzIGx1Y3RhdG9yKi4KCiMjIEdlb2dyYXBoaWNhbCBiaWFzIGluIGh5ZHJvcmVndWxhdGlvbiBzdHVkaWVzIHstfQoKYGBge3IgRmlnIFM0LCBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy5oZWlnaHQ9My41LCBmaWcud2lkdGg9NywgZWNobyA9IEZBTFNFfQp3aWxkX2RhdCA8LSByYXdfZGF0ICU+JSBkcGx5cjo6ZmlsdGVyKG9yaWdpbiA9PSAid2lsZCIpCmxhYl9kYXQgIDwtIHJhd19kYXQgJT4lIGRwbHlyOjpmaWx0ZXIob3JpZ2luID09ICJsYWIiKQoKd29ybGRfbWFwIDwtIG1hcF9kYXRhKCJ3b3JsZCIpCnJhd19kYXQgJT4lCiAgZ2dwbG90KCkgKwogIGdlb21fbWFwKGRhdGEgPSB3b3JsZF9tYXAgJT4lIGRwbHlyOjpmaWx0ZXIocmVnaW9uICE9ICJBbnRhcmN0aWNhIiksIG1hcCA9IHdvcmxkX21hcCwgYWVzKGxvbmcsIGxhdCwgbWFwX2lkID0gcmVnaW9uKSwgZmlsbCA9ICIjZGVkZWRlIiwgY29sb3VyID0gTkEpICsKICBnZW9tX3BvaW50KGFlcyh4ID0gbG9uLCB5ID0gbGF0KSkgKwogIHNjYWxlX2NvbG91cl9kaXNjcmV0ZV9zZXF1ZW50aWFsKHBhbGV0dGUgPSAiVmlyaWRpcyIpICsKICBzY2FsZV95X2NvbnRpbnVvdXMoZXhwYW5kID0gYygwLCAwKSkgKwogIHNjYWxlX3hfY29udGludW91cyhleHBhbmQgPSBjKDAsIDApKSArCiAgdGhlbWVfdm9pZCgpICsgCiAgdGhlbWUoYXhpcy50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRleHQgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50aWNrcyA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCkpICsKICBjb29yZF9maXhlZCgpCmBgYAoKKipGaWcuIFM0LioqIFNwYXRpYWwgZGlzdHJpYnV0aW9uIG9mIGh5ZHJvcmVndWxhdGlvbiBzdHVkaWVzIHVzaW5nIHdpbGQgY2F1Z2h0IGFudXJhbnMgKHN0dWR5ICpuKiA9IGByIGxlbmd0aCh1bmlxdWUod2lsZF9kYXQkc3R1ZHlfSUQpKWApLiBgciBsZW5ndGgodW5pcXVlKGxhYl9kYXQkc3R1ZHlfSUQpKWAgc3R1ZGllcyB1c2VkIGNhcHRpdmUgcmFpc2VkIGFudXJhbnMuIFRoZXJlIGFyZSBsYXJnZSByZWdpb25zIGFyb3VuZCBjZW50cmFsIEFmcmljYSBhbmQgRXVyYXNpYSB3aXRoIGhpZ2ggYW1waGliaWFuIGRpdmVyc2l0eSwgYnV0IG5vIGh5ZHJvbG9naWNhbCBzdHVkaWVzIGNvbmR1Y3RlZCAoKipGaWcuIDFiKiopLiAKCioqKgoKIyMgUHJlcGFyZSBwaHlsb2dlbnkgZm9yIGFuYWx5c2lzIHstfQoKVGhlIHBoeWxvZ2VueSB3YXMgb2J0YWluZWQgZnJvbSBASmV0ejIwMTggY29tcHJpc2luZyBvZiA3LDIzOCBzcGVjaWVzLiBUaGUgdHJlZSB3YXMgcHJ1bmVkIHRvIG1hdGNoIHRoZSBzcGVjaWVzIGV4dHJhY3RlZCBmb3IgdGhlIHN1YnNlcXVlbnQgYW5hbHlzaXMuCgpgYGB7ciBwaHlsbywgbWVzc2FnZT1GQUxTRSwgcmVzdWx0cz0iaGlkZSJ9CiMgTG9hZCB0cmVlCnBoeWxvX3RyZWUgPC0gYXBlOjpyZWFkLnRyZWUoZmlsZS5wYXRoKGRhdGFfcGF0aCwgImFtcGhfc2hsX25ld19Db25zZW5zdXNfNzIzOC50cmUiKSkKCiMgUHJ1bmluZyBkYXRhIGFuZCBwaHlsb2dlbnkKdHJlZV90aXBfbGFiZWwgPC0gcGh5bG9fdHJlZSR0aXAubGFiZWwgIyBleHRyYWN0IHRyZWUgdGlwIG5hbWVzCnNwX2xpc3QgICAgICAgIDwtIHJhd19kYXQkc3BlY2llc19waHlsbyAjIGV4dHJhY3Qgc3BlY2llcyBuYW1lIGZyb20gbWVhbiBkYXRhCnBydW5lZF90cmVlICAgIDwtIGFwZTo6ZHJvcC50aXAocGh5bG9fdHJlZSwgc2V0ZGlmZihwaHlsb190cmVlJHRpcC5sYWJlbCwgc3BfbGlzdCkpICMgcHJ1bmUgcGh5bG9fdHJlZSB0byBrZWVwIHNwZWNpZXMgZnJvbSB0aGUgcmF3IGRhdGEKcHJ1bmVkX3RyZWUgICAgPC0gcGh5dG9vbHM6OmZvcmNlLnVsdHJhbWV0cmljKHBydW5lZF90cmVlLCBtZXRob2QgPSAiZXh0ZW5kIikgIyB1bHRyYW1ldHJpY2l6ZSB0aGUgdHJlZQpwaHlsb19jb3IgICAgICA8LSB2Y3YocHJ1bmVkX3RyZWUsIGNvciA9IFQpCgpzZXRkaWZmKHJhd19kYXQkc3BlY2llc19waHlsbywgcm93bmFtZXMocGh5bG9fY29yKSkKc2V0ZGlmZihyb3duYW1lcyhwaHlsb19jb3IpLCByYXdfZGF0JHNwZWNpZXNfcGh5bG8pCgojYXBlOjppcy51bHRyYW1ldHJpYyhwcnVuZWRfdHJlZSkKYGBgCgojIEFuYWx5c2lzIHstfQoKVGhlIG9yaWdpbmFsIG1vZGVsIGluY29ycG9yYXRlZCBvcmlnaW4gKGxhYi1yYWlzZWQgb3Igd2lsZC1jYXVnaHQpIGFuZCB3aGV0aGVyIHRoZSBibGFkZGVyIHdhcyB2b2lkIG9mIHVyaW5lIHByaW9yIHRvIHRoZSBleHBlcmltZW50LiBIb3dldmVyLCB0aGUgbW9kZWwncyBidWxrIGVmZmVjdGl2ZSBzYW1wbGVzIHNpemUgKEVTUykgd2FzIHRvbyBsb3csIGluZGljYXRpbmcgcG9zdGVyaW9yIG1lYW5zIGFuZCBtZWRpYW5zIG1heSBiZSB1bnJlbGlhYmxlLiBTaW5jZSBvcmlnaW4gYW5kIHdoZXRoZXIgdGhlIGJsYWRkZXIgd2FzIGVtcHRpZWQgZGlkIG5vdCBpbmZsdWVuY2UgRVdMLCB0aGV5IHdlcmUgZXhjbHVkZWQgaW4gdGhlIGZpbmFsIG1vZGVsLiBGb3IgdHJhbnNwYXJlbmN5LCBvbiBhdmVyYWdlLCB3aWxkLWNhdWdodCBhbnVyYW5zIGhhZCwgb24gYXZlcmFnZSwgbG93ZXIgRVdMIHJlbGF0aXZlIHRvIGxhYi1yYWlzZWQgYW51cmFucyAoLTAuMDggWy0wLjQ3OjAuMzFdKSwgYW5kIGFudXJhbnMgd2l0aCB0aGVpciBibGFkZGVyIHZvaWRlZCBvZiB1cmluZSBoYWQgbG93ZXIgRVdMICgtMC4xNyBbLTAuNTk6IDAuMjVdKS4gSG93ZXZlciB0aGVyZSBpcyBzdWJzdGFudGlhbCB2YXJpYWJpbGl0eSBiZXR3ZWVuIHRoZSB3aWxkLWNhdWdodCBhbmQgbGFiLXJhaXNlZCBncm91cHMsIGFuZCB3aGV0aGVyIGFudXJhbnMgd2l0aCB0aGVpciBibGFkZGVyIHZvaWRlZCBvciBub3QuCgpgYGB7ciBld2wsIG1lc3NhZ2U9RkFMU0UsIGNhY2hlPVRSVUUsIHJlc3VsdHM9ImhpZGUifQojb3B0aW9ucyhicm1zLmJhY2tlbmQgPSAiY21kc3RhbnIiKSAjIEVycm9yIGZyb20gdXNpbmcgUnN0YW5zICJlcnJvciBpbiB1bnNlcmlhbGl6ZShzb2NrbGlzdFtbbl1dKSA6IGVycm9yIHJlYWRpbmcgZnJvbSBjb25uZWN0aW9uIi4gVXNlZCBjbWRzdGFuciBhcm91bmQgaXQuCgpwcmlvcnMgPC0gYyhwcmlvcihub3JtYWwoMCwgMyksICdiJyksIAogICAgICAgICAgICBwcmlvcihub3JtYWwoMCwgMyksICdJbnRlcmNlcHQnKSwKICAgICAgICAgICAgcHJpb3Ioc3R1ZGVudF90KDMsIDAsIDEwKSwgJ3NkJyksIAogICAgICAgICAgICBwcmlvcihzdHVkZW50X3QoMywgMCwgMTApLCAnc2lnbWEnKSkKCmV3bF9tb2RlbCA8LSBicm1zOjpicm0obG5NZWFuIH4gZWNvdHlwZSArIHN0cmF0ZWd5ICsgbG5NYXNzICsgbG5WUEQgKyBsbkZsb3cgKyAoMSB8IHN0dWR5X0lEKSArICgxICsgbG5NYXNzIHwgc3BlY2llc19pdWNuKSArICgxIHwgZ3Ioc3BlY2llc19waHlsbywgY292ID0gcGh5bG8pKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhICAgID0gZXdsX2RhdCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYW1pbHkgID0gZ2F1c3NpYW4oKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhMiAgID0gbGlzdChwaHlsbyA9IHBoeWxvX2NvciksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcmlvciAgID0gcHJpb3JzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hhaW5zICA9IDQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29yZXMgICA9IDQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXRlciAgICA9IDVlMywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3YXJtdXAgID0gMi41ZTMsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udHJvbCA9IGxpc3QoYWRhcHRfZGVsdGEgPSAwLjk5LCBtYXhfdHJlZWRlcHRoID0gMTUpKQoKd3VfbW9kZWwgPC0gYnJtczo6YnJtKGxuTWVhbiB+IGVjb3R5cGUgKyBsbk1hc3MgKyB0cnRfdGVtcCArIGh5ZHJhdGlvbiArIG9yaWdpbiArICgxIHwgc3R1ZHlfSUQpICsgKDEgKyBsbk1hc3MgfCBzcGVjaWVzX2l1Y24pICsgKDEgfCBncihzcGVjaWVzX3BoeWxvLCBjb3YgPSBwaHlsbykpLCAKICAgICAgICAgICAgICAgICAgICAgICBkYXRhICAgID0gd3VfZGF0ICU+JSAKICAgICAgICAgICAgICAgICAgICAgICAgZHBseXI6Omdyb3VwX2J5KGVjb3R5cGUpICU+JSAKICAgICAgICAgICAgICAgICAgICAgICAgZHBseXI6OmZpbHRlcihuKCkgPj0gNSksIAogICAgICAgICAgICAgICAgICAgICAgIGZhbWlseSAgPSBnYXVzc2lhbigpLCAKICAgICAgICAgICAgICAgICAgICAgICBkYXRhMiAgID0gbGlzdChwaHlsbyA9IHBoeWxvX2NvciksCiAgICAgICAgICAgICAgICAgICAgICAgcHJpb3IgICA9IHByaW9ycywKICAgICAgICAgICAgICAgICAgICAgICBjaGFpbnMgID0gNCwgCiAgICAgICAgICAgICAgICAgICAgICAgY29yZXMgICA9IDQsIAogICAgICAgICAgICAgICAgICAgICAgIGl0ZXIgICAgPSA1ZTMsIAogICAgICAgICAgICAgICAgICAgICAgIHdhcm11cCAgPSAyLjVlMywgCiAgICAgICAgICAgICAgICAgICAgICAgY29udHJvbCA9IGxpc3QoYWRhcHRfZGVsdGEgPSAwLjk5LCBtYXhfdHJlZWRlcHRoID0gMTUpKQpgYGAKCmBgYHtyIEZpZyBTNSwgZWNobyA9IEZBTFNFLCBmaWcud2lkdGggPSA3LCBmaWcuaGVpZ2h0ID0gMywgZmlnLmFsaWduID0nIGNlbnRlcid9CmV3bF9tb2RlbF9wcCA8LSBicm1zOjpwcF9jaGVjayhld2xfbW9kZWwsIHR5cGUgPSAic2NhdHRlcl9hdmciKQp3dV9tb2RlbF9wcCAgPC0gYnJtczo6cHBfY2hlY2sod3VfbW9kZWwsIHR5cGUgPSAic2NhdHRlcl9hdmciKQoKY293cGxvdDo6cGxvdF9ncmlkKGV3bF9tb2RlbF9wcCwgd3VfbW9kZWxfcHAsIG5jb2wgPSAyLCBsYWJlbHMgPSBjKCdhJywgJ2InKSkKYGBgCgoqKkZpZy4gUzUuKiogU2NhdHRlcnBsb3RzIG9mIHRoZSBvYnNlcnZlZCBkYXRhICh5KSB2cyB0aGUgYXZlcmFnZSBzaW11bGF0ZWQgZGF0YSAoeX5yZXB+KSBmcm9tIHRoZSBwb3N0ZXJpb3IgcHJlZGljdGl2ZSBkaXN0cmlidXRpb24gZm9yIHRoZSAoKiphKiopIGV2YXBvcmF0aXZlIHdhdGVyIGxvc3MgbW9kZWwsIGFuZCAoKipiKiopIHRoZSB3YXRlciB1cHRha2UgbW9kZWwuIERhc2hlZCBsaW5lIHJlcHJlc2VudHMgYSBzbG9wZSBvZiAxLiAKCiMjIE1vZGVsIG91dHB1dCB7LnRhYnNldCAudGFic2V0LWZhZGUgLnRhYnNldC1waWxscyAtfQoKIyMjIFRhYmxlIFMzIC0gRVdMIG1vZGVsIHsudGFic2V0IC50YWJzZXQtZmFkZSAudGFic2V0LXBpbGxzIC19IAoKKipUYWJsZSBTMy4qKiBNZWFuIHBhcmFtZXRlciBlc3RpbWF0ZXMsIGVzdGltYXRlIGVycm9yLCBhbmQgOTUlIEJheWVzaWFuIGNyZWRpYmxlIGludGVydmFscyBmb3IgdGhlIGV2YXBvcmF0aXZlIHdhdGVyIGxvc3MgbW9kZWwsIHdoaWNoIGluY2x1ZGVzIHRoZSBpbnRlcmNlcHQgKCRcYmV0YV8wJCksIGVjb3R5cGUsIHN0cmF0ZWd5LCB0aGUgbmF0dXJhbCBsb2dhcml0aG0gb2YgYm9keSBtYXNzIChsbk1hc3MpLCB0aGUgbmF0dXJhbCBsb2dhcml0aG0gb2YgdmFwb3VyIHByZXNzdXJlIGRlZmljaXQgKGxuVlBEKSwgYW5kIHRoZSBuYXR1cmFsIGxvZ2FyaXRobSBvZiB0aGUgZXhwZXJpbWVudGFsIGZsb3cgcmF0ZSAobG5GbG93KS4gR3JvdXAtbGV2ZWwgZWZmZWN0cyBpbmNsdWRlIHRoZSBzdGFuZGFyZCBkZXZpYXRpb25zICgkXHNpZ21hJCkgZm9yIHN0dWR5LWxldmVsIG9ic2VydmF0aW9ucyAoJFxzaWdtYV97c3R1ZHl9XjIkKSwgcGh5bG9nZW5ldGljIHJlbGF0ZWRuZXNzICgkXHNpZ21hX3twaHlsb2dlbnl9XjIkKSwgYW5kIHRoZSBjb3JyZWxhdGlvbiBhbW9uZyBzcGVjaWVzICgkXHNpZ21hX3tzcGVjaWVzfV4yJCkgYW5kIGJvZHkgbWFzcyAoJFxzaWdtYV97bG5NYXNzfV4yJCkuICRSX3ttYXJnaW5hbH1eMiQgcmVwcmVzZW50cyB0aGUgdmFyaWFuY2UgZXhwbGFpbmVkIGJ5IGZpeGVkIGVmZmVjdHMsIHdoaWxlICRSX3tjb25kaXRpb25hbH1eMiQgcmVwcmVzZW50cyB0aGUgdmFyaWFuY2UgZXhwbGFpbmVkIGJ5IGJvdGggZml4ZWQgZWZmZWN0cyBhbmQgZ3JvdXAtbGV2ZWwgZWZmZWN0cy4KCmBgYHtyIHRhYmxlUzMsIGVjaG8gPSBGQUxTRX0KIyBGaXhlZCBlZmZlY3QKZmVmIDwtIGJybXM6OmZpeGVmKGV3bF9tb2RlbCkgJT4lIAogIGFzLmRhdGEuZnJhbWUoLikgJT4lCiAgdGliYmxlOjpyb3duYW1lc190b19jb2x1bW4oIlBhcmFtZXRlciIpICU+JSAKICBkcGx5cjo6bXV0YXRlKFBhcmFtZXRlciA9IHN0cl9yZXBsYWNlKFBhcmFtZXRlciwgIk0iLCAiLSIpKSAlPiUgCiAgZHBseXI6Om11dGF0ZShQYXJhbWV0ZXIgPSBjYXNlX3doZW4oCiAgICBQYXJhbWV0ZXIgPT0gIkludGVyY2VwdCIgfiAibG4kXFxiZXRhXzAkIiwKICAgIFBhcmFtZXRlciA9PSAiZWNvdHlwZUFyYm9yZWFsIiAgfiAiQXJib3JlYWwiLAogICAgUGFyYW1ldGVyID09ICJlY290eXBlRm9zc29yaWFsIiAgfiAiRm9zc29yaWFsIiwKICAgIFBhcmFtZXRlciA9PSAiZWNvdHlwZUdyb3VuZC1kd2VsbGluZyIgIH4gIkdyb3VuZC1kd2VsbGluZyIsCiAgICBQYXJhbWV0ZXIgPT0gImVjb3R5cGVTZW1pLWFxdWF0aWMiICB+ICJTZW1pLWFxdWF0aWMiLAogICAgUGFyYW1ldGVyID09ICJlY290eXBlU3RyZWFtLWR3ZWxsaW5nIiAgfiAiU3RyZWFtLWR3ZWxsaW5nIiwKICAgIFBhcmFtZXRlciA9PSAic3RyYXRlZ3l3YXRlci1wcm9vZiIgIH4gIldhdGVyLXByb29mIiwKICAgIFBhcmFtZXRlciA9PSAic3RyYXRlZ3ljb2Nvb24iICB+ICJDb2Nvb24iLAogICAgUGFyYW1ldGVyID09ICJzdHJhdGVneWhvbGxvdyIgIH4gIkhvbGxvdyIsCiAgICBQYXJhbWV0ZXIgPT0gImxuLWFzcyIgIH4gImxuTWFzcyIsCiAgICBQYXJhbWV0ZXIgPT0gImxuVlBEIiAgfiAibG5WUEQiLAogICAgUGFyYW1ldGVyID09ICJsbkZsb3ciICB+ICJsbkZsb3ciKSwKICAgICkgJT4lIAogIHRpYmJsZTo6YWRkX3JvdyhQYXJhbWV0ZXIgPSAiKipGaXhlZCBlZmZlY3RzKioiLCAuYmVmb3JlID0gMSkKCiMgUmFuZG9tIGVmZmVjdApyZWYgPC0gc3VtbWFyeShld2xfbW9kZWwpJHJhbmRvbSAlPiUgCiAgYmluZF9yb3dzKCkgJT4lICMgdW5saXN0CiAgdGliYmxlOjpyb3duYW1lc190b19jb2x1bW4oIlBhcmFtZXRlciIpICU+JSAKICBkcGx5cjo6c2VsZWN0KDE6NSkgJT4lIAogIGRwbHlyOjptdXRhdGUoUGFyYW1ldGVyID0gYygiJFxcc2lnbWFfe3NwZWNpZXN9XjIkIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIkXFxzaWdtYV97bG5NYXNzfV4yJCIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiY29yKCRcXHNpZ21hX3tzcGVjaWVzfV4yJCwgJFxcc2lnbWFfe2xuTWFzc31eMiQpIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIkXFxzaWdtYV97cGh5bG9nZW55fV4yJCIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiJFxcc2lnbWFfe3N0dWR5fV4yJCIpKSAlPiUgICAKICBkcGx5cjo6cmVuYW1lKFEyLjUgID0gNCwgCiAgICAgICAgICAgICAgICBROTcuNSA9IDUpICU+JSAKICB0aWJibGU6OmFkZF9yb3coUGFyYW1ldGVyID0gIioqR3JvdXAtbGV2ZWwgZWZmZWN0cyoqIiwgLmJlZm9yZSA9IDEpCgpld2xfbGFtYmRhIDwtIGh5cG90aGVzaXMoZXdsX21vZGVsLCAic2Rfc3BlY2llc19waHlsb19fSW50ZXJjZXB0XjIgLyAoc2Rfc3BlY2llc19waHlsb19fSW50ZXJjZXB0XjIgKyBzaWdtYV4yKSA9IDAiLCBjbGFzcyA9IE5VTEwpJGh5cG90aGVzaXMgJT4lIAogIGRwbHlyOjpzZWxlY3QoLWMoMSw2OjgpKSAlPiUgCiAgZHBseXI6Om11dGF0ZShQYXJhbWV0ZXIgPSAiJFxcbGFtYmRhJCIpICU+JSAKICBkcGx5cjo6cmVuYW1lKFEyLjUgID0gQ0kuTG93ZXIsIAogICAgICAgICAgICAgICAgUTk3LjUgPSBDSS5VcHBlcikgJT4lIAogIHRpYmJsZTo6YWRkX3JvdyhQYXJhbWV0ZXIgPSAiKipQaHlsb2dlbmV0aWMgc2lnbmFsKioiLCAuYmVmb3JlID0gMSkKCmV3bF9yMiA8LSBkYXRhLmZyYW1lKFBhcmFtZXRlciA9ICIkUl97bWFyZ2luYWx9XjIkIiwKICAgICAgICAgICAgICAgICAgICAgRXN0aW1hdGUgPSByb3VuZChkYXRhLmZyYW1lKHBlcmZvcm1hbmNlOjpyMl9iYXllcyhld2xfbW9kZWwpKVsyLDFdLCA0KSAqIDEwMCwKICAgICAgICAgICAgICAgICAgICAgUTIuNSAgICAgPSByb3VuZChkYXRhLmZyYW1lKHBlcmZvcm1hbmNlOjpyMl9iYXllcyhld2xfbW9kZWwpKVsyLDRdLCA0KSAqIDEwMCwKICAgICAgICAgICAgICAgICAgICAgUTk3LjUgICAgPSByb3VuZChkYXRhLmZyYW1lKHBlcmZvcm1hbmNlOjpyMl9iYXllcyhld2xfbW9kZWwpKVsyLDVdLCA0KSAqIDEwMCkgJT4lCiAgdGliYmxlOjphZGRfcm93KFBhcmFtZXRlciA9ICIkUl97Y29uZGl0aW9uYWx9XjIkIiwKICAgICAgICAgICAgICAgICAgICAgRXN0aW1hdGUgPSByb3VuZChkYXRhLmZyYW1lKHBlcmZvcm1hbmNlOjpyMl9iYXllcyhld2xfbW9kZWwpKVsxLDFdLCA0KSAqIDEwMCwKICAgICAgICAgICAgICAgICAgICAgUTIuNSAgICAgPSByb3VuZChkYXRhLmZyYW1lKHBlcmZvcm1hbmNlOjpyMl9iYXllcyhld2xfbW9kZWwpKVsxLDRdLCA0KSAqIDEwMCwKICAgICAgICAgICAgICAgICAgICAgUTk3LjUgICAgPSByb3VuZChkYXRhLmZyYW1lKHBlcmZvcm1hbmNlOjpyMl9iYXllcyhld2xfbW9kZWwpKVsxLDVdLCA0KSAqIDEwMCkgJT4lIAogIHRpYmJsZTo6YWRkX3JvdyhQYXJhbWV0ZXIgPSAiKipWYXJpYW5jZSoqIiwgLmJlZm9yZSA9IDEpCgojIFJlbmRlciB0YWJsZQpiaW5kX3Jvd3MoZmVmLCByZWYsIGV3bF9sYW1iZGEsIGV3bF9yMikgJT4lIAogIHJlbW92ZV9yb3duYW1lcygpICU+JSAKICBrbml0cjo6a2FibGUoZGlnaXRzID0gMikKYGBgCgojIyMgVGFibGUgUzQgLSBXVSBtb2RlbCB7LnRhYnNldCAudGFic2V0LWZhZGUgLnRhYnNldC1waWxscyAtfSAKCioqVGFibGUgUzQuKiogTWVhbiBwYXJhbWV0ZXIgZXN0aW1hdGVzLCBlc3RpbWF0ZSBlcnJvciwgYW5kIDk1JSBCYXllc2lhbiBjcmVkaWJsZSBpbnRlcnZhbHMgZm9yIHRoZSB3YXRlciB1cHRha2UgbW9kZWwsIHdoaWNoIGluY2x1ZGVzIHRoZSBpbnRlcmNlcHQgKCRcYmV0YV8wJCksIGVjb3R5cGUsIHRoZSBuYXR1cmFsIGxvZ2FyaXRobSBvZiBib2R5IG1hc3MgKGxuTWFzcyksIHRyZWF0bWVudCB0ZW1wZXJhdHVyZSwgaW5pdGlhbCBoeWRyYXRpb24gbGV2ZWwsIGFuZCBvcmlnaW4gKGxhYi1yYWlzZWQgb3Igd2lsZCBjYXVnaHQpLiBHcm91cC1sZXZlbCBlZmZlY3RzIGluY2x1ZGUgdGhlIHN0YW5kYXJkIGRldmlhdGlvbnMgKCRcc2lnbWEkKSBmb3Igc3R1ZHktbGV2ZWwgb2JzZXJ2YXRpb25zICgkXHNpZ21hX3tzdHVkeX1eMiQpLCBwaHlsb2dlbmV0aWMgcmVsYXRlZG5lc3MgKCRcc2lnbWFfe3BoeWxvZ2VueX1eMiQpLCBhbmQgdGhlIGNvcnJlbGF0aW9uIGFtb25nIHNwZWNpZXMgKCRcc2lnbWFfe3NwZWNpZXN9XjIkKSBhbmQgYm9keSBtYXNzICgkXHNpZ21hX3tsbk1hc3N9XjIkKS4gJFJfe21hcmdpbmFsfV4yJCByZXByZXNlbnRzIHRoZSB2YXJpYW5jZSBleHBsYWluZWQgYnkgZml4ZWQgZWZmZWN0cywgd2hpbGUgJFJfe2NvbmRpdGlvbmFsfV4yJCByZXByZXNlbnRzIHRoZSB2YXJpYW5jZSBleHBsYWluZWQgYnkgYm90aCBmaXhlZCBlZmZlY3RzIGFuZCBncm91cC1sZXZlbCBlZmZlY3RzLgoKYGBge3IgdGFibGVTNSwgZWNobyA9IEZBTFNFfQojIEZpeGVkIGVmZmVjdApmZWYgPC0gYnJtczo6Zml4ZWYod3VfbW9kZWwpICU+JSAKICBhcy5kYXRhLmZyYW1lKC4pICU+JQogIHRpYmJsZTo6cm93bmFtZXNfdG9fY29sdW1uKCJQYXJhbWV0ZXIiKSAlPiUgCiAgZHBseXI6Om11dGF0ZShQYXJhbWV0ZXIgPSBzdHJfcmVwbGFjZShQYXJhbWV0ZXIsICJNIiwgIi0iKSkgJT4lIAogIGRwbHlyOjptdXRhdGUoUGFyYW1ldGVyID0gY2FzZV93aGVuKAogICAgUGFyYW1ldGVyID09ICJJbnRlcmNlcHQiIH4gImxuJFxcYmV0YV8wJCIsCiAgICBQYXJhbWV0ZXIgPT0gImVjb3R5cGVGb3Nzb3JpYWwiICB+ICJGb3Nzb3JpYWwiLAogICAgUGFyYW1ldGVyID09ICJlY290eXBlR3JvdW5kLWR3ZWxsaW5nIiAgfiAiR3JvdW5kLWR3ZWxsaW5nIiwKICAgIFBhcmFtZXRlciA9PSAiZWNvdHlwZVNlbWktYXF1YXRpYyIgIH4gIlNlbWktYXF1YXRpYyIsCiAgICBQYXJhbWV0ZXIgPT0gImxuLWFzcyIgIH4gImxuTWFzcyIsCiAgICBQYXJhbWV0ZXIgPT0gInRydF90ZW1wIiAgfiAiVHJlYXRtZW50IHRlbXBlcmF0dXJlIiwKICAgIFBhcmFtZXRlciA9PSAiaHlkcmF0aW9uIiAgfiAiSW5pdGlhbCBoeWRyYXRpb24iLAogICAgUGFyYW1ldGVyID09ICJvcmlnaW53aWxkIiAgfiAiT3JpZ2luIC0gV2lsZCIsCiAgICAgICAgVFJVRSAgIH4gUGFyYW1ldGVyKSkgJT4lIAogIHRpYmJsZTo6YWRkX3JvdyhQYXJhbWV0ZXIgPSAiKipGaXhlZCBlZmZlY3RzKioiLCAuYmVmb3JlID0gMSkKCiMgUmFuZG9tIGVmZmVjdApyZWYgPC0gc3VtbWFyeSh3dV9tb2RlbCkkcmFuZG9tICU+JSAKICBiaW5kX3Jvd3MoKSAlPiUgIyB1bmxpc3QKICB0aWJibGU6OnJvd25hbWVzX3RvX2NvbHVtbigiUGFyYW1ldGVyIikgJT4lIAogIGRwbHlyOjpzZWxlY3QoMTo1KSAlPiUgCiAgZHBseXI6Om11dGF0ZShQYXJhbWV0ZXIgPSBjKCIkXFxzaWdtYV97c3BlY2llc31eMiQiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiRcXHNpZ21hX3tsbk1hc3N9XjIkIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJjb3IoJFxcc2lnbWFfe3NwZWNpZXN9XjIkLCAkXFxzaWdtYV97bG5NYXNzfV4yJCkiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiRcXHNpZ21hX3twaHlsb2dlbnl9XjIkIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIkXFxzaWdtYV97c3R1ZHl9XjIkIikpICU+JSAgIAogIGRwbHlyOjpyZW5hbWUoUTIuNSAgPSA0LCAKICAgICAgICAgICAgICAgIFE5Ny41ID0gNSkgJT4lIAogIHRpYmJsZTo6YWRkX3JvdyhQYXJhbWV0ZXIgPSAiKipHcm91cC1sZXZlbCBlZmZlY3RzKioiLCAuYmVmb3JlID0gMSkKCnd1X2xhbWJkYSA8LSBoeXBvdGhlc2lzKHd1X21vZGVsLCAic2Rfc3BlY2llc19waHlsb19fSW50ZXJjZXB0XjIgLyAoc2Rfc3BlY2llc19waHlsb19fSW50ZXJjZXB0XjIgKyBzaWdtYV4yKSA9IDAiLCBjbGFzcyA9IE5VTEwpJGh5cG90aGVzaXMgJT4lIAogIGRwbHlyOjpzZWxlY3QoLWMoMSw2OjgpKSAlPiUgCiAgZHBseXI6Om11dGF0ZShQYXJhbWV0ZXIgPSAiJFxcbGFtYmRhJCIpICU+JSAKICBkcGx5cjo6cmVuYW1lKFEyLjUgID0gQ0kuTG93ZXIsIAogICAgICAgICAgICAgICAgUTk3LjUgPSBDSS5VcHBlcikgJT4lIAogIHRpYmJsZTo6YWRkX3JvdyhQYXJhbWV0ZXIgPSAiKipQaHlsb2dlbmV0aWMgc2lnbmFsKioiLCAuYmVmb3JlID0gMSkKCnd1X3IyIDwtIGRhdGEuZnJhbWUoUGFyYW1ldGVyID0gIiRSX3ttYXJnaW5hbH1eMiQiLAogICAgICAgICAgICAgICAgICAgICBFc3RpbWF0ZSA9IHJvdW5kKGRhdGEuZnJhbWUocGVyZm9ybWFuY2U6OnIyX2JheWVzKHd1X21vZGVsKSlbMiwxXSwgNCkgKiAxMDAsCiAgICAgICAgICAgICAgICAgICAgIFEyLjUgICAgID0gcm91bmQoZGF0YS5mcmFtZShwZXJmb3JtYW5jZTo6cjJfYmF5ZXMod3VfbW9kZWwpKVsyLDRdLCA0KSAqIDEwMCwKICAgICAgICAgICAgICAgICAgICAgUTk3LjUgICAgPSByb3VuZChkYXRhLmZyYW1lKHBlcmZvcm1hbmNlOjpyMl9iYXllcyh3dV9tb2RlbCkpWzIsNV0sIDQpICogMTAwKSAlPiUKICB0aWJibGU6OmFkZF9yb3coUGFyYW1ldGVyID0gIiRSX3tjb25kaXRpb25hbH1eMiQiLAogICAgICAgICAgICAgICAgICAgICBFc3RpbWF0ZSA9IHJvdW5kKGRhdGEuZnJhbWUocGVyZm9ybWFuY2U6OnIyX2JheWVzKHd1X21vZGVsKSlbMSwxXSwgNCkgKiAxMDAsCiAgICAgICAgICAgICAgICAgICAgIFEyLjUgICAgID0gcm91bmQoZGF0YS5mcmFtZShwZXJmb3JtYW5jZTo6cjJfYmF5ZXMod3VfbW9kZWwpKVsxLDRdLCA0KSAqIDEwMCwKICAgICAgICAgICAgICAgICAgICAgUTk3LjUgICAgPSByb3VuZChkYXRhLmZyYW1lKHBlcmZvcm1hbmNlOjpyMl9iYXllcyh3dV9tb2RlbCkpWzEsNV0sIDQpICogMTAwKSAlPiUgCiAgdGliYmxlOjphZGRfcm93KFBhcmFtZXRlciA9ICIqKlZhcmlhbmNlKioiLCAuYmVmb3JlID0gMSkKCiMgUmVuZGVyIHRhYmxlCmJpbmRfcm93cyhmZWYsIHJlZiwgd3VfbGFtYmRhLCB3dV9yMikgJT4lIAogIHJlbW92ZV9yb3duYW1lcygpICU+JSAKICBrbml0cjo6a2FibGUoZGlnaXRzID0gMikKYGBgCgojIyMgRmlnLiBTNiAtIEVXTCBtb2RlbCB7LnRhYnNldCAudGFic2V0LWZhZGUgLnRhYnNldC1waWxscyAtfSAKCmBgYHtyIEZpZyBTNiwgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcuaGVpZ2h0PTcsIGZpZy53aWR0aD03LCBlY2hvID0gRkFMU0V9CmV3bF9jZSA8LSBicm1zOjpjb25kaXRpb25hbF9lZmZlY3RzKGV3bF9tb2RlbCwgYygiZWNvdHlwZSIsICJzdHJhdGVneSIpKQpld2xfZWNvX2NlIDwtIGRhdGEuZnJhbWUoZXdsX2NlW1sxXV0pICU+JQogIGRwbHlyOjpyZW5hbWUoZXN0aW1hdGUgPSBlc3RpbWF0ZV9fLCBjaS5sYiA9IGxvd2VyX18sIGNpLnViID0gdXBwZXJfXykKZXdsX3N0cmFfY2UgPC0gYXMuZGF0YS5mcmFtZShld2xfY2VbWzJdXSkgJT4lCiAgZHBseXI6OnJlbmFtZShlc3RpbWF0ZSA9IGVzdGltYXRlX18sIGNpLmxiID0gbG93ZXJfXywgY2kudWIgPSB1cHBlcl9fKQoKZXdsX2Vjb19wbG90IDwtIGV3bF9lY29fY2UgJT4lCiAgZ2dwbG90KGFlcyh4ID0gZWNvdHlwZSwgeSA9IGV4cChlc3RpbWF0ZSkpKSArIAogIGdnZm9yY2U6Omdlb21fc2luYShkYXRhID0gZXdsX2RhdCAlPiUgZHBseXI6OmZpbHRlcihzdHJhdGVneSAlaW4lIGMoIm5vbmUiLCAid2F0ZXItcHJvb2YiKSksIGFlcyh4ID0gZWNvdHlwZSwgeSA9IG1nX2hfbWVhbiwgc2l6ZSA9IGludiksIGNvbG91ciA9ICIjZGVkZWRlIikgKyAKICBnZW9tX3BvaW50KGFlcygpLCBzaXplID0gNCwgc2hvdy5sZWdlbmQgPSBGQUxTRSkgKwogIGdlb21fZXJyb3JiYXIoYWVzKHltaW4gPSBleHAoY2kubGIpLCB5bWF4ID0gZXhwKGNpLnViKSksIHNpemUgPSAwLjgsIHdpZHRoID0gMC4xLCBzaG93LmxlZ2VuZCA9IEZBTFNFKSArCiAgc2NhbGVfeV9jb250aW51b3VzKHRyYW5zID0gc2NhbGVzOjpsb2dfdHJhbnMoKSwgYnJlYWtzID0gYygwLjEsIDEsIDEwLCAxMDAsIDEwMDApLCBsYWJlbHMgPSBjKDAuMSwgMSwgMTAsIDEwMCwgIjEsMDAwIikpICsKICBsYWJzKHggPSBOVUxMLCBzaXplID0gIlByZWNpc2lvbiIpICsgCiAgeWxhYihleHByZXNzaW9uKCJFV0wifigibWcifkhbMl0qT35oXnsiLTEifSkpKSArCiAgbXl0aGVtZSgpICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIpCgpld2xfc3RyYV9wbG90IDwtIGV3bF9zdHJhX2NlICU+JQogIGdncGxvdChhZXMoeCA9IHN0cmF0ZWd5LCB5ID0gZXhwKGVzdGltYXRlKSkpICsgCiAgZ2dmb3JjZTo6Z2VvbV9zaW5hKGRhdGEgPSBld2xfZGF0LCBhZXMoeCA9IHN0cmF0ZWd5LCB5ID0gbWdfaF9tZWFuLCBzaXplID0gaW52KSwgY29sb3VyID0gIiNkZWRlZGUiLCBtYXh3aWR0aCA9IDAuNSkgKyAKICBnZW9tX3BvaW50KGFlcygpLCBzaXplID0gNCwgc2hvdy5sZWdlbmQgPSBGQUxTRSkgKwogIGdlb21fZXJyb3JiYXIoYWVzKHltaW4gPSBleHAoY2kubGIpLCB5bWF4ID0gZXhwKGNpLnViKSksIHNpemUgPSAwLjgsIHdpZHRoID0gMC4xLCBzaG93LmxlZ2VuZCA9IEZBTFNFKSArCiAgc2NhbGVfeV9jb250aW51b3VzKHRyYW5zID0gc2NhbGVzOjpsb2dfdHJhbnMoKSwgYnJlYWtzID0gYygwLjEsIDEsIDEwLCAxMDAsIDEwMDApLCBsYWJlbHMgPSBjKDAuMSwgMSwgMTAsIDEwMCwgIjEsMDAwIikpICsKICBsYWJzKHggPSAiU3RyYXRlZ3kiLCBzaXplID0gIlByZWNpc2lvbiIpICsgCiAgeWxhYihleHByZXNzaW9uKCJFV0wifigibWcifkhbMl0qT35oXnsiLTEifSkpKSArCiAgbXl0aGVtZSgpICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIpCgpjb3dwbG90OjpwbG90X2dyaWQoZXdsX2Vjb19wbG90LCBld2xfc3RyYV9wbG90LCBsYWJlbHMgPSBjKCdhJywgJ2InKSwgbmNvbCA9IDEsIGFsaWduID0gJ3YnLCBheGlzID0gJ2wnKQpgYGAKCioqRmlnLiBTNi4qKiBEaWZmZXJlbmNlcyBpbiBldmFwb3JhdGl2ZSB3YXRlciBsb3NzIChtZyBIfjJ+TyBoXi0xXikgYnkgKCoqYSoqKSBlY290eXBlIGFuZCAoKipiKiopIHdhdGVyLWNvbnNlcnZpbmcgc3RyYXRlZ2llcy4gTm90ZSwgd2hlbiBwbG90dGluZyBieSBlY290eXBlLCB0aGUgZXZhcG9yYXRpdmUgbG9zcyBleGNsdWRlcyBiZWhhdmlvdXJhbCB3YXRlci1jb25zZXJ2aW5nIHN0cmF0ZWdpZXMgc3VjaCBhcyBkdXJpbmcgY29jb29uLWZvcm1pbmcgYW5kIGluc2lkZSBob2xsb3dzLiBNZWFuIGVzdGltYXRlcyDCsSA5NSUgQ0kgcHJlc2VudGVkIGluIGJsYWNrIHBvaW50cyBhbmQgZXJyb3IgYmFycywgd2hpbGUgcmF3IHZhbHVlcyB3ZXJlIHByZXNlbnRlZCBhcyBncmV5IHBvaW50cy4gVGhlIHNpemUgb2YgdGhlIGdyZXkgcG9pbnRzIGluZGljYXRlcyBzdHVkeSBwcmVjaXNpb24gKGludmVyc2Ugb2Ygc3RhbmRhcmQgZXJyb3IpLgoKIyMjIEZpZy4gUzcgLSBXVSBtb2RlbCB7LnRhYnNldCAudGFic2V0LWZhZGUgLnRhYnNldC1waWxscyAtfSAKCmBgYHtyIEZpZyBTNywgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcuaGVpZ2h0PTMuNSwgZmlnLndpZHRoPTcsIGVjaG8gPSBGQUxTRX0Kd3VfY2UgPC0gYnJtczo6Y29uZGl0aW9uYWxfZWZmZWN0cyh3dV9tb2RlbCwgYygiZWNvdHlwZSIsICJsbk1hc3MiLCAiaHlkcmF0aW9uIikpCnd1X2Vjb19jZSA8LSBkYXRhLmZyYW1lKHd1X2NlW1sxXV0pICU+JQogIGRwbHlyOjpyZW5hbWUoZXN0aW1hdGUgPSBlc3RpbWF0ZV9fLCBjaS5sYiA9IGxvd2VyX18sIGNpLnViID0gdXBwZXJfXykKCnd1X2Vjb19jZSAlPiUKICBnZ3Bsb3QoYWVzKHggPSBlY290eXBlLCB5ID0gZXhwKGVzdGltYXRlKSkpICsgCiAgZ2dmb3JjZTo6Z2VvbV9zaW5hKGRhdGEgPSB3dV9kYXQsIGFlcyh4ID0gZWNvdHlwZSwgeSA9IG1nX2hfbWVhbiwgc2l6ZSA9IGludiksIGNvbG91ciA9ICIjZGVkZWRlIikgKyAKICBnZW9tX3BvaW50KGFlcygpLCBzaXplID0gNCwgc2hvdy5sZWdlbmQgPSBGQUxTRSkgKwogIGdlb21fZXJyb3JiYXIoYWVzKHltaW4gPSBleHAoY2kubGIpLCB5bWF4ID0gZXhwKGNpLnViKSksIHNpemUgPSAwLjgsIHdpZHRoID0gMC4xLCBzaG93LmxlZ2VuZCA9IEZBTFNFKSArCiAgc2NhbGVfeV9jb250aW51b3VzKHRyYW5zID0gc2NhbGVzOjpsb2dfdHJhbnMoKSwgYnJlYWtzID0gYygxMCwgMTAwLCAxMDAwLCAxMDAwMCwgMTAwMDAwKSwgbGFiZWxzID0gYygxMCwgMTAwLCAiMSwwMDAiLCAiMTAsMDAwIiwgIjEwMCwwMDAiKSkgKwogIGxhYnMoeCA9IE5VTEwsIHNpemUgPSAiUHJlY2lzaW9uIikgKyAKICB5bGFiKGV4cHJlc3Npb24oIldVIn4oIm1nIn5IWzJdKk9+aF57Ii0xIn0pKSkgKwogIG15dGhlbWUoKSArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iKQpgYGAKCioqRmlnLiBTNy4qKiBEaWZmZXJlbmNlcyBpbiBjdXRhbmVvdXMgd2F0ZXIgdXB0YWtlIChtZyBIfjJ+TyBoXi0xXikgYnkgZWNvdHlwZS4gTWVhbiBlc3RpbWF0ZXMgwrEgOTUlIENJIHByZXNlbnRlZCBpbiBibGFjayBwb2ludHMgYW5kIGVycm9yIGJhcnMsIHdoaWxlIHJhdyB2YWx1ZXMgd2VyZSBwcmVzZW50ZWQgYXMgZ3JleSBwb2ludHMuIFRoZSBzaXplIG9mIHRoZSBncmV5IHBvaW50cyBpbmRpY2F0ZXMgc3R1ZHkgcHJlY2lzaW9uIChpbnZlcnNlIG9mIHN0YW5kYXJkIGVycm9yKS4KCioqKgoKIyAqTmljaGVNYXBSKiB7LX0KClRvIGVzdGltYXRlIHRoZSBpbmZsdWVuY2Ugb2Ygd2FybWluZyBhbmQgZHJvdWdodCBvbiBhY3Rpdml0eSBvZiBhIGh5cG90aGV0aWNhbCBmcm9nLCB3ZSBzaW11bGF0ZWQgYSB3YXRlciBhbmQgaGVhdCBlbmVyZ3kgZXhjaGFuZ2UgbW9kZWwgKCoqRmlnLiBTOGEqKikgYW5kIGl0cyBpbnRlcmFjdGlvbiB3aXRoIGEgc2ltdWxhdGVkIGxvY2FsIG1pY3JvY2xpbWF0ZSB1c2luZyB0aGUgKk5pY2hlTWFwUiogcGFja2FnZSBbQEtlYXJuZXkyMDE3OyBAS2Vhcm5leTIwMjBdLgoKIVtdKEZpZyBTOCAtIEVuZXJneSBhbmQgd2F0ZXIgZXhjaGFuZ2UucG5nKQoKKipGaWcuIFM4LioqIFN1bW1hcnkgd2F0ZXIgYW5kIGVuZXJneSBleGNoYW5nZSBtb2RlbCBmcm9tIEBUcmFjeTE5NzYgaW50ZWdyYXRlZCBpbnRvICpOaWNoZU1hcFIqIGFuZCB3YXRlciBjb25zZXJ2aW5nIHN0cmF0ZWdpZXMuICgqKmEqKikgU2NoZW1hdGljIHN1bW1hcnkgb2YgdGhlIGV4Y2hhbmdlcyBvZiBlbmVyZ3kgYW5kIHdhdGVyIGJldHdlZW4gYSBmcm9nIGFuZCBpdHMgZW52aXJvbm1lbnQgdXNlZCB0byBkZXZlbG9wIHRoZSB0cmFuc2llbnQtc3RhdGUgbW9kZWwgb2Ygd2F0ZXIgZXhjaGFuZ2UuIEluIHJlc3BlY3QgdG8gd2F0ZXIgZXhjaGFuZ2UsIHRoZSBuZXQgd2F0ZXIgbG9zcyByZXByZXNlbnRzIHdhdGVyIGxvc3MgZnJvbSByZXNwaXJhdG9yeSwgY3V0YW5lb3VzLCBvY3VsYXIsIGFuZCBjbG9hY2EgZXZhcG9yYXRpb24gYXMgd2VsbCBhcyB1cmluYXJ5IGFuZCBmYWVjYWwgd2F0ZXIgW0BQaXJ0bGUyMDE5XS4gKCoqYioqKSBCZWhhdmlvdXJhbCwgbW9ycGhvbG9naWNhbCwgYW5kIHBoeXNpb2xvZ2ljYWwgc3RyYXRlZ2llcyBlbXBsb3llZCBieSBmcm9ncyBvbiBsYW5kIHRvIHJlZHVjZSB3YXRlciBsb3NzIFtASGlsbG1hbjIwMDldLgoKIyMgU2ltdWxhdGUgd2F0ZXItY29uc2VydmluZyBiZWhhdmlvdXJzIHstfQoKV2UgbW9kaWZpZWQgdGhlIGN1cnJlbnQgYGVjdG9SX2RldmVsYCBmdW5jdGlvbiBmcm9tICpOaWNoZU1hcFIqIHYzLjIuMSB0byBhY2NvdW50IGZvciB0aGUgaW5mbHVlbmNlIG9mIGh5ZHJhdGlvbiBvbiBhY3Rpdml0eSAoYGJlaGF2X2Z1bmN0aW9uc2AgZnVuY3Rpb24pIHdoaWNoIGNhbiBiZSBmb3VuZCBpbiB0aGUgW2JlaGF2X2Z1bmN0aW9ucy5SXShodHRwczovL2dpdGh1Yi5jb20vbmljaG9sYXN3dW56L2dsb2JhbC1mcm9nLWRyb3VnaHQvYmxvYi9tYWluL2NvZGUvYmVoYXZfZnVuY3Rpb25zLlIpIGZpbGUgb24gR2l0SHViLiAKCioqQXNrIFVydHppIHRvIGVsYWJvcmF0ZSBhbmQgbW9kaWZ5IHRoaXMgc2VjdGlvbioqIHdoYXQgd2FzIGNoYW5nZWQgYW5kIHdoYXQgaXQgcmVwcmVzZW50cwoKV2hlbiB0aGUgYW5pbWFsIGlzIG5vdCBhY3RpdmUgKGkuZS4gaXMgYmVsb3cgZ3JvdW5kKSwgaXQgaXMgc2ltdWxhdGVkIHRvIGdvIHRvIGFuIHVuZGVyZ3JvdW5kIHJldHJlYXQuIEl0IHNlbGVjdHMgdGhlIHNoYWxsb3dlc3QgZGVwdGggd2l0aCB0ZW1wZXJhdHVyZXMgYmV0d2VlbiBUbWF4IGFuZCBUbWluLiBJZiB3YXRlciA9IFQsIHRoZSBmcm9nIHNlbGVjdHMgdGhlIHNoYWxsb3dlc3Qgbm9kZSB3aXRoIHRlbXBlcmF0dXJlcyBiZXR3ZWVuIFRtYXggYW5kIFRtaW4gYW5kIGEgd2F0ZXIgcG90ZW50aWFsID49IC03Mi41LCB3aGljaCB3YXMgcmVwb3J0ZWQgYXMgYSBzb2lsIHdhdGVyIHBvdGVudGlhbCBmcm9tIHdoaWNoICpSYW5hIHBpcGllbnMqIGNvdWxkIGFic29yYiB3YXRlci4gV2hlbiB0aGUgYW5pbWFsIGlzIGJlbG93Z3JvdW5kLCBpdCByZS1oeWRyYXRlcyBhdCBhIHJhdGUgc3BlY2lmaWVkIGluIGh5ZC5yYXRlLCBpZiB0aGUgc29pbCB3YXRlciBwb3RlbnRpYWwgaXMgPj0gLTcyLjUuIEltcG9ydGFudCB0byBub3RlIHRoYXQgY3VycmVudGx5IGZyb2dzIGFyZSBub3QgcmUtaHlkcmF0aW5nIHdoZW4gYWN0aXZlIGFib3ZlZ3JvdW5kLgoKVGhlIOKAnHNraW53ZXTigJ0gdGVybSAoJHBfe3dldH0kKSBkZXRlcm1pbmVzIHRoZSBwcm9wb3J0aW9uIG9mIHRoZSB0b3RhbCBzdXJmYWNlIGFyZWEgdXNlZCBpbiB0aGUgY2FsY3VsYXRpb24gb2YgbWFzcyB0cmFuc2ZlciBvZiB3YXRlciBmcm9tIHRoZSBzdXJmYWNlLiBIZXJlLCAkcF97d2V0fSQgd2FzIGNhbGN1bGF0ZWQgZnJvbSBlbXBpcmljYWxseSBkZXJpdmVkIHNraW4gcmVzaXN0YW5jZSBmb2xsb3dpbmcgQFBpcnRsZTIwMTk6CgpcYmVnaW57ZXF1YXRpb259CnBfe3dldH0gPSBcZnJhY3sxfXtoX0QgXHRpbWVzIHJfaSArIChcZnJhY3tQX3J9e1NfY30pXlxmcmFjezJ9ezN9fSwgCihcI2VxOnB3ZXQpClxlbmR7ZXF1YXRpb259Cgp3aGVyZSAkcl9pJCBpcyB0aGUgc2tpbuKAmXMgcmVzaXN0YW5jZSB0byB3YXRlciB2YXBvciB0cmFuc2ZlciAocyBtXi0xXiksICRQX3IkIGlzIHRoZSBQcmFuZHRsIG51bWJlciAoZGltZW5zaW9ubGVzcyksICRTX2MkIGlzIHRoZSBTY2htaWR0IG51bWJlciAoZGltZW5zaW9ubGVzcyksICRoX0QkIGlzIHRoZSBtYXNzIHRyYW5zZmVyIGNvZWZmaWNpZW50IChtIHNeLTFeKS4gVG8gY2FsY3VsYXRlICRwX3t3ZXR9JCwgdGhlIG1hc3MgdHJhbnNmZXIgY29lZmZpY2llbnQgKCRoX0QkKSBtdXN0IGJlIGtub3duLiBNYXNzIHRyYW5zZmVyIHJlZmVycyB0byB0aGUgbW92ZW1lbnQgb2YgYSBzdWJzdGFuY2UgdGhvdWdoIGEgZmx1aWQgaW50ZXJmYWNlLCBkcml2ZW4gYnkgY2hhbmdlcyBpbiB0aGUgY29uY2VudHJhdGlvbiBncmFkaWVudC4gVGhlIG1hc3MgdHJhbnNmZXIgY29lZmZpY2llbnQgY29udHJvbHMgdGhlIHJhdGUgb2YgZGlmZnVzaW9uIGFuZCBpcyBkZXBlbmRlbnQgb24gdmVsb2NpdHksIHRlbXBlcmF0dXJlLCBhbmQgcGh5c2ljYWwgcHJvcGVydGllcyBvZiB0aGUgaW50ZXJwaGFzZS4gU2ltaWxhciB0byB0aGUgaGVhdCB0cmFuc2ZlciBjb2VmZmljaWVudCwgdGhlIG1hc3MgdHJhbnNmZXIgY29lZmZpY2llbnQgYWxzbyBoYXMgdHdvIGNvbXBvbmVudHMgZGVyaXZlZCBmcm9tIGZyZWUgYW5kIGZvcmNlZCBjb252ZWN0aW9uLiBXZSBjb25zaWRlciBmb3JjZWQgY29udmVjdGlvbiBvbmx5IChhcyBmcmVlIGNvbnZlbnRpb24gc2hvdWxkIGJlIG5lZ2xpZ2libGUgd2l0aGluIGEgbWVhc3VyZW1lbnQgY2hhbWJlciksIGFuZCB0aGlzIGNhbiBiZSBjYWxjdWxhdGVkIGZyb20gdGhlIGhlYXQgdHJhbnNmZXIgY29lZmZpY2llbnQ6CgpcYmVnaW57ZXF1YXRpb259CmhfRCA9IChcZnJhY3toX0N9e0NfcCBcdGltZXMgXHJob30pIFx0aW1lcyAoXGZyYWN7UF9yfXtTX2N9KSBeIFxmcmFjezJ9ezN9LCAKKFwjZXE6aGQpClxlbmR7ZXF1YXRpb259Cgp3aGVyZSAkUF9yJCBpcyB0aGUgUHJhbmR0bCBudW1iZXIgKGRpbWVuc2lvbmxlc3MpLCAkU19jJCBpcyB0aGUgU2NobWlkdCBudW1iZXIgKGRpbWVuc2lvbmxlc3MpLCAkaF9DJCBpcyB0aGUgaGVhdCB0cmFuc2ZlciBjb2VmZmljaWVudCAoSiBzXi0xXiBjbV4tMl4gS14tMV4pLCAkXHJobyQgaXMgdGhlIGRlbnNpdHkgb2YgZHJ5IGFpciAoZyBjbV4tM14pLCBhbmQgJENfcCQgaXMgdGhlIHNwZWNpZmljIGhlYXQgb2YgYWlyICgxLjAxIEogZ14tMV4gS14tMV4pLgoKIyMgU2ltdWxhdGUgZHJvdWdodCBhbmQgd2FybWluZyB7LX0KCk1pY3JvY2xpbWF0ZXMgcmVwcmVzZW50IHRoZSBwaHlzaWNhbCBlbnZpcm9ubWVudHMgZXhwZXJpZW5jZWQgYnkgYW4gb3JnYW5pc20uIFRoZXkgYXJlIGEgbmVjZXNzaXR5IGZvciBtZWNoYW5pc3RpYyBuaWNoZSBtb2RlbGxpbmcgYmVjYXVzZSBpdCBpcyB0aGUgZW52aXJvbm1lbnQgZXhwZXJpZW5jZWQgYXQgdGhlIHNjYWxlIG9mIHRoZSBpbmRpdmlkdWFsIHRoYXQgbmVlZHMgdG8gYmUgcHJvdmlkZWQgdG8gdGhlIGVxdWF0aW9ucyBvZiBlbmVyZ3kgYW5kIG1hc3MgYmFsYW5jZS4gVGhlIG1pY3JvY2xpbWF0ZSBtb2RlbCB3YXMgaW1wbGVtZW50ZWQgYXMgZGVzY3JpYmVkIGJ5IEBLZWFybmV5MjAxNC4gU3BlY2lmaWNhbGx5LCBpdCB3YXMgZHJpdmVuIGJ5IGhpc3RvcmljYWwgMC4wNcKwIGdyaWQgKH41IGttKSBkYWlseSB3ZWF0aGVyIGlucHV0IGxheWVycyAoYWlyIHRlbXBlcmF0dXJlLCB2YXBvciBwcmVzc3VyZSwgd2luZCBzcGVlZCwgYW5kIGNsb3VkIGNvdmVyKS4KCldlIHNpbXVsYXRlZCBtZXRlb3JvbG9naWNhbCBkcm91Z2h0IChkZWZpbmVkIGFzIGxlc3MgdGhhbiBhdmVyYWdlIHJhaW5mYWxsKSBieSBtb2RpZnlpbmcgdGhlIGBtaWNyb19lcmE1YCBmdW5jdGlvbiBmcm9tICpOaWNoZU1hcFIqIHRvIGluY29ycG9yYXRlIHJhaW5mYWxsIChgcmFpbmZhY3RgKSBhbmQgcmVsYXRpdmUgaHVtaWRpdHkgKGByaGZhY3RgKSBkZWZpY2l0IGZhY3RvcnMuIEEgZGVmYXVsdCBmYWN0b3IgaXMgMSB3aGljaCBpcyAxMDAlIG9mIHRoZSBvcmlnaW5hbCByYWluZmFsbCBvciByZWxhdGl2ZSBodW1pZGl0eS4gQSBmYWN0b3Igb2YgMC41IG1lYW5zIDUwJSBvZiB0aGUgb3JpZ2luYWwgcmFpbmZhbGwgb3IgcmVsYXRpdmUgaHVtaWRpdHkuIFRoZSBtb2RpZmllZCBmdW5jdGlvbiBjYW4gYmUgZm91bmQgb24gdGhlIGFjY29tcGFueWluZyBHaXRIdWIgcGFnZS4KClRvIHNpbXVsYXRlIGZyb2cgYWN0aXZpdHkgdW5kZXIgZHJvdWdodCBhbmQgd2FybWluZyBzY2VuYXJpb3MsIHdlIGNvbnN0cnVjdGVkIGZvdXIgY2xpbWF0ZSBjb25kaXRpb25zIHVzaW5nIHRoZSBgbWljcm9fZXJhNWAgZnVuY3Rpb246IAoKMS4gKipjdXJyZW50IG5vcm1hbCBzY2VuYXJpbyoqIHJlcHJlc2VudGluZyB0aGUgbWVhbiBhbm51YWwgYWlyIHRlbXBlcmF0dXJlIGFuZCByYWluZmFsbCBmcm9tIDE5ODHigJMyMDEwLAoyLiAqKmN1cnJlbnQgZHJvdWdodCBzY2VuYXJpbyoqIHJlcHJlc2VudGluZyB0aGUgbWVhbiBhbm51YWwgYWlyIHRlbXBlcmF0dXJlIGZyb20gMTk4MS0yMDEwIGFuZCBhbm51YWwgcmFpbmZhbGwgYmFzZWQgb24gMjAxNy0yMDE5IGRyb3VnaHQgaW4gQXVzdHJhbGlhICgqKkZpZy4gUzkqKiksCjMuICoqd2FybWluZyBub3JtYWwgc2NlbmFyaW8qKiByZXByZXNlbnRpbmcgdGhlIOKAnGJ1c2luZXNzLWFzLXVzdWFs4oCdIHNjZW5hcmlvLCB3aGVyZSB0aGUgZ2xvYmFsIHN1cmZhY2UgdGVtcGVyYXR1cmUgaXMgZXN0aW1hdGVkIHRvIGluY3JlYXNlIGJ5IDTCsEMgYnkgMjA4MOKAkzIxMDAgd2l0aCBubyBlZmZlY3Qgb2YgZHJvdWdodCAoKzTCsEMgb25seSksIGFuZCAKNC4gKip3YXJtaW5nIGRyb3VnaHQgc2NlbmFyaW8qKiB3aXRoIGEgKzTCsEMgaW5jcmVhc2luZyBpbiBhaXIgdGVtcGVyYXR1cmUgYW5kIGFubnVhbCByYWluZmFsbCBiYXNlZCBvbiAyMDE3LTIwMTkgZHJvdWdodCBpbiBBdXN0cmFsaWEuCgpGaXJzdCwgZG93bmxvYWQgdGhlIGBtY2VyYTVgIG1pY3JvY2xpbWF0ZSBkYXRhIHRvIGEgbG9jYWwgZGlyZWN0b3J5IHRvIHJ1biB0aGUgYG1pY3JvX2VyYTVgIGZ1bmN0aW9uIGZhc3Rlci4KCmBgYHtyIG1jZXJhX3NldHVwLCBldmFsPUZBTFNFLCBlY2hvPVR9CiMgZ2V0IEVSQTUgZGF0YSB3aXRoIHBhY2thZ2UgbWNlcmE1IAojIGFzc2lnbiB5b3VyIGNyZWRlbnRpYWxzIChyZWdpc3RlciBoZXJlOiBodHRwczovL2Nkcy5jbGltYXRlLmNvcGVybmljdXMuZXUvdXNlci9yZWdpc3RlcikKdWlkICAgICAgICAgPC0gIiQkJCQkJCIKY2RzX2FwaV9rZXkgPC0gIiQkJCQkJCQkLSQkJCQtJCQkJC0kJCQkLSQkJCQkJCQkJCQkJCIKZWNtd2ZyOjp3Zl9zZXRfa2V5KHVzZXIgPSB1aWQsIGtleSA9IGNkc19hcGlfa2V5LCBzZXJ2aWNlID0gImNkcyIpCgojIGJvdW5kaW5nIGNvb3JkaW5hdGVzIChpbiBXR1M4NCAvIEVQU0c6NDMyNikKYygtNDEuMTkwLCAtMjAuMTg2KSAKeG1uIDwtIC00Mgp4bXggPC0gLTQxCnltbiA8LSAtMjEKeW14IDwtIC0yMAoKeG1uIDwtIDE1Mgp4bXggPC0gMTU0CnltbiA8LSAtMjgKeW14IDwtIC0yNgoKIyB0ZW1wb3JhbCBleHRlbnQKc3RfdGltZSA8LSBsdWJyaWRhdGU6OnltZCgiMjAxNjowMTowMSIpICMgZWFybGllc3Qgc2FtcGxpbmcgZGF0ZQplbl90aW1lIDwtIGx1YnJpZGF0ZTo6eW1kKCIyMDE4OjEyOjMxIikgIyBsYXRlc3Qgc2FtcGxpbmcgZGF0ZQoKIyBmaWxlbmFtZSBhbmQgbG9jYXRpb24gZm9yIGRvd25sb2FkZWQgLm5jIGZpbGVzCmZpbGVfcHJlZml4IDwtICJlcmE1IgpvcCA8LSAiWU9VUiBESVJFQ1RPUlkiCgojIGJ1aWxkIGEgcmVxdWVzdCAoY292ZXJpbmcgbXVsdGlwbGUgeWVhcnMpCnJlcSA8LSBtY2VyYTU6OmJ1aWxkX2VyYTVfcmVxdWVzdCh4bWluID0geG1uLCB4bWF4ID0geG14LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeW1pbiA9IHltbiwgeW1heCA9IHlteCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXJ0X3RpbWUgICA9IHN0X3RpbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbmRfdGltZSAgICAgPSBlbl90aW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3V0ZmlsZV9uYW1lID0gZmlsZV9wcmVmaXgpCgptY2VyYTU6OnJlcXVlc3RfZXJhNShyZXF1ZXN0ID0gcmVxLCB1aWQgPSB1aWQsIG91dF9wYXRoID0gb3ApCmBgYAoKTmV4dCwgcnVuIHRoZSBgbWljcm9fZXJhNWAgZnVuY3Rpb24gZm9yIHRoZSBmb3VyIHNjZW5hcmlvcyBpbiAyMDE3IChyZXByZXNlbnRpbmcgdHlwaWNhbCByYWluZmFsbCB5ZWFyKSwgYW5kIG9uZSBmb3IgMjAxOSB0byB2YWxpZGF0ZSB0aGUgb2JzZXJ2ZWQgcmFpbmZhbGwgZGF0YS4KCmBgYHtyIG1pY3JvX3J1biwgbWVzc2FnZT1GQUxTRSwgY2FjaGU9VFJVRSwgcmVzdWx0cz0iaGlkZSJ9CnNvdXJjZSgiL1VzZXJzL25pY2hvbGFzd3UvTGlicmFyeS9DbG91ZFN0b3JhZ2UvT25lRHJpdmUtV2VzdGVyblN5ZG5leVVuaXZlcnNpdHkvRHJvdWdodCBwcm9qZWN0L2NvZGUvbWljcm9fZXJhNV9kcm91Z2h0LlIiKQoKbG9uZ2xhdCA8LSBjKDE1My4wOTI0OSwgLTI3LjYyMzUpICMgS2FyYXdhdGhhLCBRTEQuCgojIEN1cnJlbnQgbm9ybWFsIDIwMTcgc2NlbmFyaW8KbWljcm9fY3Vycl93ZXQgPC0gbWljcm9fZXJhNShsb2MgPSBsb25nbGF0LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBydW5zaGFkZSA9IDEsIG1pbnNoYWRlID0gMCwgIyBzaGFkZSBwYXJhbWV0ZXJzCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmFpbmZhY3QgPSAxLjIsIHJoZmFjdCA9IDEsICMgcmFpbiBhbmQgUkggcGFyYW1ldGVycwogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdhcm0gPSAwLCAjIGN1cnJlbnQgY2xpbWF0ZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRzdGFydCA9ICIwMS8wMS8yMDE3IiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGZpbmlzaCA9ICIzMS8xMi8yMDE3IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzcGF0aWFsID0gJy9Vc2Vycy9uaWNob2xhc3d1L0xpYnJhcnkvQ2xvdWRTdG9yYWdlL09uZURyaXZlLVdlc3Rlcm5TeWRuZXlVbml2ZXJzaXR5L0Ryb3VnaHQgcHJvamVjdC9TcGF0aWFsIGRhdGEva2FyYXdhdGhhL2VyYTUnLCAjIGNoYW5nZSB0byB5b3VyIGxvY2F0aW9uCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2F2ZSA9IDApCgojIEN1cnJlbnQgZHJ5IDIwMTcgc2NlbmFyaW8KbWljcm9fY3Vycl9kcnkgPC0gbWljcm9fZXJhNShsb2MgPSBsb25nbGF0LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBydW5zaGFkZSA9IDEsIG1pbnNoYWRlID0gMCwgIyBzaGFkZSBwYXJhbWV0ZXJzCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmFpbmZhY3QgPSAwLjUsIHJoZmFjdCA9IDAuMSwgIyByYWluIGFuZCBSSCBwYXJhbWV0ZXJzCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2FybSA9IDAsICMgY3VycmVudCBjbGltYXRlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZHN0YXJ0ID0gIjAxLzAxLzIwMTciLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZmluaXNoID0gIjMxLzEyLzIwMTciLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNwYXRpYWwgPSAnL1VzZXJzL25pY2hvbGFzd3UvTGlicmFyeS9DbG91ZFN0b3JhZ2UvT25lRHJpdmUtV2VzdGVyblN5ZG5leVVuaXZlcnNpdHkvRHJvdWdodCBwcm9qZWN0L1NwYXRpYWwgZGF0YS9rYXJhd2F0aGEvZXJhNScsICMgY2hhbmdlIHRvIHlvdXIgbG9jYXRpb24KICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzYXZlID0gMCkKCiMgV2FybWluZyBub3JtYWwgMjAxNyBzY2VuYXJpbwptaWNyb193YXJtX3dldCA8LSBtaWNyb19lcmE1KGxvYyA9IGxvbmdsYXQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJ1bnNoYWRlID0gMSwgbWluc2hhZGUgPSAwLCAjIHNoYWRlIHBhcmFtZXRlcnMKICAgICAgICAgICAgICAgICAgICAgICAgICAgICByYWluZmFjdCA9IDEuMiwgcmhmYWN0ID0gMSwgIyByYWluIGFuZCBSSCBwYXJhbWV0ZXJzCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdhcm0gPSA0LCAjIGZ1dHVyZSBjbGltYXRlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRzdGFydCA9ICIwMS8wMS8yMDE3IiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRmaW5pc2ggPSAiMzEvMTIvMjAxNyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNwYXRpYWwgPSAnL1VzZXJzL25pY2hvbGFzd3UvTGlicmFyeS9DbG91ZFN0b3JhZ2UvT25lRHJpdmUtV2VzdGVyblN5ZG5leVVuaXZlcnNpdHkvRHJvdWdodCBwcm9qZWN0L1NwYXRpYWwgZGF0YS9rYXJhd2F0aGEvZXJhNScsICMgY2hhbmdlIHRvIHlvdXIgbG9jYXRpb24KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2F2ZSA9IDApCgojIFdhcm1pbmcgZHJ5IDIwMTcgc2NlbmFyaW8gKHNpbXVsYXRpbmcgMjAxOSBkcm91Z2h0KQptaWNyb193YXJtX2RyeSA8LSBtaWNyb19lcmE1KGxvYyA9IGxvbmdsYXQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJ1bnNoYWRlID0gMSwgbWluc2hhZGUgPSAwLCAjIHNoYWRlIHBhcmFtZXRlcnMKICAgICAgICAgICAgICAgICAgICAgICAgICAgICByYWluZmFjdCA9IDAuNSwgcmhmYWN0ID0gMC4xLCAjIHJhaW4gYW5kIFJIIHBhcmFtZXRlcnMKICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3YXJtID0gNCwgIyBmdXR1cmUgY2xpbWF0ZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRzdGFydCA9ICIwMS8wMS8yMDE3IiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGZpbmlzaCA9ICIzMS8xMi8yMDE3IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzcGF0aWFsID0gJy9Vc2Vycy9uaWNob2xhc3d1L0xpYnJhcnkvQ2xvdWRTdG9yYWdlL09uZURyaXZlLVdlc3Rlcm5TeWRuZXlVbml2ZXJzaXR5L0Ryb3VnaHQgcHJvamVjdC9TcGF0aWFsIGRhdGEva2FyYXdhdGhhL2VyYTUnLCAjIGNoYW5nZSB0byB5b3VyIGxvY2F0aW9uCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2F2ZSA9IDApCgojIFNpbXVsYXRlIHJhaW5mYWxsIGZvciAyMDE5IGRyb3VnaHQKYWN0X2RyeSA8LSBtaWNyb19lcmE1KGxvYyA9IGxvbmdsYXQsIAogICAgICAgICAgICAgICAgICAgICAgcnVuc2hhZGUgPSAxLCBtaW5zaGFkZSA9IDAsICMgc2hhZGUgcGFyYW1ldGVycwogICAgICAgICAgICAgICAgICAgICAgd2FybSA9IDAsICMgY3VycmVudCBjbGltYXRlCiAgICAgICAgICAgICAgICAgICAgICBkc3RhcnQgPSAiMDEvMDEvMjAxOSIsIAogICAgICAgICAgICAgICAgICAgICAgZGZpbmlzaCA9ICIzMS8xMi8yMDE5IiwKICAgICAgICAgICAgICAgICAgICAgIHNwYXRpYWwgPSAnL1VzZXJzL25pY2hvbGFzd3UvTGlicmFyeS9DbG91ZFN0b3JhZ2UvT25lRHJpdmUtV2VzdGVyblN5ZG5leVVuaXZlcnNpdHkvRHJvdWdodCBwcm9qZWN0L1NwYXRpYWwgZGF0YS9rYXJhd2F0aGEvZXJhNScsICMgY2hhbmdlIHRvIHlvdXIgbG9jYXRpb24KICAgICAgICAgICAgICAgICAgICAgIHNhdmUgPSAwKQpgYGAKClRvIHZlcmlmeSBvdXIgbWljcm9jbGltYXRlIG1vZGVscywgd2UgcGxvdHRlZCB0aGUgc2ltdWxhdGVkIHRoZSBkYWlseSByYWluZmFsbCBmb3IgMjAxNyAocmVwcmVzZW50aW5nIHR5cGljYWwgcmFpbmZhbGwpIGFuZCAyMDE5IChoaXN0b3JpY2FsIGRyb3VnaHQpIHdpdGggdGhlIFtvYnNlcnZlZCBkYWlseSByYWluZmFsbCBdKGh0dHA6Ly93d3cuYm9tLmdvdi5hdS9jbGltYXRlL2Ryb3VnaHQva25vd2xlZGdlLWNlbnRyZS9wcmV2aW91cy1kcm91Z2h0cy5zaHRtbCkgaW4gQXVzdHJhbGlhIGZvciB0aGUgZm9sbG93aW5nIGxvY2F0aW9uOiBLYXJhd2F0aGEsIFNvdXRoZWFzdCBRdWVlbnNsYW5kLCBBdXN0cmFsaWEgKDE1My4wOTI0OSwgLTI3LjYyMzUpLiBLYXJhd2F0aGEgcHJvdmlkZXMgYSBnb29kIGNhc2Ugc3R1ZHkgYmVjYXVzZSB0aGVyZSBhcmUgbWFueSBlY290eXBlcyBmb3VuZCBpbiB0aGlzIGxvY2F0aW9uOiBncm91bmQtZHdlbGxpbmcgKGUuZy4gKlJoaW5lbGxhIG1hcmluYSopLCBhcmJvcmVhbCAoZS5nLiAqTGl0b3JpYSBjYWVydWxlYSopLCBmb3Nzb3JpYWwgKGUuZy4gKkN5Y2xvcmFuYSBhbGJvZ3V0dGF0YSopLCBzZW1pLWFxdWF0aWMgKGUuZy4gKkxpdG9yaWEgbmFzdXRhKiksIGFuZCB0aGlzIGFyZWEgaGFzIGV4cGVyaWVuY2VkIGRyb3VnaHQgcmVjZW50bHkgKDIwMTkpLiBXZSBleHRyYWN0ZWQgcmFpbmZhbGwgZGF0YSBmcm9tIGEgd2VhdGhlciBzdGF0aW9uIG5leHQgdG8gS2FyYXdhdGhhIHdoaWNoIGV4cGVyaWVuY2VkICJ2ZXJ5IG11Y2ggYmVsb3cgYXZlcmFnZSIgcmFpbmZhbGwgZnJvbSB0aGUgQXVzdHJhbGlhbiBCdXJlYXUgb2YgTWV0ZW9yb2xvZ3kuCgpgYGB7ciBGaWcgUzksIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLmhlaWdodD0zLjUsIGZpZy53aWR0aD04fQojIExvYWQgb2JzZXJ2ZWQgcmFpbmZhbGwgZm9yIDIwMTkKb2JzX3JhaW5mYWxsIDwtIHJlYWQuY3N2KGZpbGUucGF0aChkYXRhX3BhdGgsICJvYnNfcmFpbmZhbGwuY3N2IikpICU+JQogIHRpYmJsZTo6cm93aWRfdG9fY29sdW1uKCJET1kiKSAlPiUKICBkcGx5cjo6bXV0YXRlKGRhdGUgPSBsdWJyaWRhdGU6Om1ha2VfZGF0ZSh5ZWFyID0gMjAxOSwgbW9udGggPSBtb250aF9udW0sIGRheSA9IGRheSkpCgojIE1lcmdlIG9ic2VydmVkIGFuZCBwcmVkaWN0ZWQgcmFpbmZhbGwgdG9nZXRoZXIKCm1vZGVsX3JhaW5fd2V0IDwtIGFzLmRhdGEuZnJhbWUobWljcm9fY3Vycl93ZXQkUkFJTkZBTEwpICU+JQogIHRpYmJsZTo6cm93aWRfdG9fY29sdW1uKCJET1kiKSAlPiUKICByZW5hbWUocmFpbmZhbGxfbW0gPSAibWljcm9fY3Vycl93ZXQkUkFJTkZBTEwiKSAlPiUKICBtZXJnZShvYnNfcmFpbmZhbGwsIGJ5ID0gIkRPWSIsIGFsbC54ID0gVFJVRSkKCm1vZGVsXzIwMTkgPC0gYXMuZGF0YS5mcmFtZShhY3RfZHJ5JFJBSU5GQUxMKSAlPiUKICB0aWJibGU6OnJvd2lkX3RvX2NvbHVtbigiRE9ZIikgJT4lCiAgcmVuYW1lKHJhaW5mYWxsX21tID0gImFjdF9kcnkkUkFJTkZBTEwiKSAlPiUKICBtZXJnZShvYnNfcmFpbmZhbGwsIGJ5ID0gIkRPWSIsIGFsbC54ID0gVFJVRSkKCiMgMjAxOSBkcm91Z2h0IHZhbGlkYXRlCnJhaW5fZHJ5X3Bsb3QgPC0gbW9kZWxfMjAxOSAlPiUKICBnZ3Bsb3QoKSArCiAgZ2VvbV9saW5lKGFlcyh4ID0gRE9ZLCB5ID0ga2FyYXdhdGhhXzE5KSwgY29sb3VyID0gImdyZXkiKSArCiAgZ2VvbV9saW5lKGFlcyh4ID0gRE9ZLCB5ID0gcmFpbmZhbGxfbW0pLCBjb2xvdXIgPSAicmVkIiwgYWxwaGEgPSAwLjUpICsKICBsYWJzKHggPSBOVUxMLCB5ID0gJ0RhaWx5IHJhaW5mYWxsIChtbSknKSArCiAgZ2d0aXRsZSgiMjAxOSBEcm91Z2h0IikgKwogIHNjYWxlX3lfY29udGludW91cyhsaW0gPSBjKDAsIDEwMCksIGV4cGFuZCA9IGMoMCwgMCkpICsKICBzY2FsZV94X2NvbnRpbnVvdXMoZXhwYW5kID0gYygwLCAwKSkgKwogIG15dGhlbWUoKSArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iKQoKIyAyMDE3IG5vcm1hbCB2YWxpZGF0ZQpyYWluX3dldF9wbG90IDwtIG1vZGVsX3JhaW5fd2V0ICU+JQogIGdncGxvdCgpICsKICBnZW9tX2xpbmUoYWVzKHggPSBET1ksIHkgPSBrYXJhd2F0aGFfMTcpLCBjb2xvdXIgPSAiZ3JleSIpICsKICBnZW9tX2xpbmUoYWVzKHggPSBET1ksIHkgPSByYWluZmFsbF9tbSksIGNvbG91ciA9ICJyZWQiLCBhbHBoYSA9IDAuNSkgKwogIGxhYnMoeCA9IE5VTEwsIHkgPSAnRGFpbHkgcmFpbmZhbGwgKG1tKScpICsKICBnZ3RpdGxlKCIyMDE3IE5vcm1hbCIpICsKICBzY2FsZV95X2NvbnRpbnVvdXMobGltID0gYygwLCAxMDApLCBleHBhbmQgPSBjKDAsIDApKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGV4cGFuZCA9IGMoMCwgMCkpICsKICBteXRoZW1lKCkgKyB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIikKCmNvd3Bsb3Q6OnBsb3RfZ3JpZChyYWluX3dldF9wbG90LCByYWluX2RyeV9wbG90LCBuY29sID0gMikKYGBgCgoqKkZpZy4gUzkuKiogU2ltdWxhdGVkIHJhaW5mYWxsIGZyb20gdGhlIGBtaWNyb19lcmE1YCBmdW5jdGlvbiAocmVkKSBhbmQgdGhlIG9ic2VydmVkIHJhaW5mYWxsIGZvciBLYXJhd2F0aGEsIFFMRCBmcm9tIHRoZSBBdXN0cmFsaWFuIEJ1cmVhdSBvZiBNZXRlb3JvbG9neSAoZ3JleSkuIFRoZSB0b3RhbCB5ZWFybHkgb2JzZXJ2ZWQgcmFpbmZhbGwKZm9yIDIwMTcgd2FzIGFzICoqYHIgc3VtKG1vZGVsX3JhaW5fd2V0JGthcmF3YXRoYV8xNylgIG1tKiosIGFuZCB0aGUgdG90YWwgc2ltdWxhdGVkIHllYXJseSByYWluZmFsbCBmcm9tICpOaWNoZU1hcFIqIHdhcyAqKmByIHN1bShtb2RlbF9yYWluX3dldCRyYWluZmFsbF9tbSlgIG1tKiouIFRoZSB0b3RhbCB5ZWFybHkgb2JzZXJ2ZWQgcmFpbmZhbGwgZm9yIHRoZSAyMDE5IGRyb3VnaHQgd2FzICoqYHIgc3VtKG1vZGVsXzIwMTkka2FyYXdhdGhhXzE5KWAgbW0qKiwgYW5kIHRoZSB0b3RhbCBzaW11bGF0ZWQgeWVhcmx5IHJhaW5mYWxsIGZyb20gKk5pY2hlTWFwUiogd2FzICoqYHIgc3VtKG1vZGVsXzIwMTkkcmFpbmZhbGxfbW0pYCBtbSoqLiBUaGUgYXZlcmFnZSB5ZWFybHkgcmFpbmZhbGwgYWNyb3NzIDE5ODEtMjAxMCBpcyBhcm91bmQgKioxMTAwIG1tKiogcGVyIHllYXIuCgojIyBTaW11bGF0ZSBhY3Rpdml0eSB7LX0KCldlIHNpbXVsYXRlZCB0aGUgcG90ZW50aWFsIG51bWJlciBvZiBob3VycyBmb3IgYWN0aXZpdHkgaW4gYSB5ZWFyICgkdF97YWN0fSQpIHdoaWNoIHJlcHJlc2VudHMgdGhlIHN1aXRhYmxlIHRoZXJtYWwgYW5kIGh5ZHJpYyBjb25kaXRpb25zIGZvciB0aGUgYW5pbWFsIHRvIG1vdmUgYmV5b25kIHRoZWlyIHJldHJlYXQgdG8gZWl0aGVyIGNhdGNoIHByZXkgb3IgZmluZGluZyBtYXRlcyBbQEtlYXJuZXkyMDIwXS4gVGhlIHRoZXJtb3JlZ3VsYXRvcnkgYW5kIGh5ZHJvcmVndWxhdG9yeSBzZXF1ZW5jZSBpbiB0aGUgbW9kZWwgYXNzdW1lcyB0aGF0IGZyb2dzIHdpbGwgb25seSBiZSDigJhhY3RpdmXigJkgKGkuZS4gbW92aW5nIGJleW9uZCB0aGVpciByZXRyZWF0LCBjYXRjaGluZyBwcmV5LCBmaW5kaW5nIG1hdGVzKSBiZXR3ZWVuIHRoZSBtaW5pbXVtIGFuZCBtYXhpbXVtIGJvZHkgdGVtcGVyYXR1cmUgdGhyZXNob2xkcyBmb3IgZm9yYWdpbmcsIGBUbWluYCBhbmQgYFRtYXhgICjCsEMpLCBhbmQgdGhlIG1pbmltdW0gdG9sZXJhdGVkIGh5ZHJhdGlvbiwgYG1pbi5oeWRgICglKS4gSW4gYWRkaXRpb24sIGlmIGB3YXRlci5hY3QgPSBUYCwgdGhlIGZyb2cgd2lsbCBvbmx5IGJlIGFjdGl2ZSBpZiB0ZW1wZXJhdHVyZXMgYXJlIHdpdGhpbiB0aGUgc3VpdGFibGUgdGVtcCByYW5nZSwgYW5kIHRoZSBmcm9nIGlzIG5vdCBleHBlY3RlZCB0byBnbyBiZWxvdyBhbGxvd2VkIGh5ZHJhdGlvbiBsZXZlbHMgKGUuZy4gaWYgJWh5ZHJhdGlvbiBpcyBub3QgYmVsb3cgYG1pbi5oeWRgKS4KClRvIGVzdGltYXRlIHRoZSBwb3RlbnRpYWwgJHRfe2FjdH0kIGZvciBvbmUgeWVhciwgd2Ugc2ltdWxhdGVkIHRoZSBoeXBvdGhldGljYWwgZnJvZyB0byBiZSBhY3RpdmUgZHVyaW5nIHRoZSBkYXkgYW5kIG5pZ2h0ICgyNCBob3VycykuIFdoaWxlIG1vc3QgZnJvZ3MgYXJlIG5vY3R1cm5hbCwgdGhlcmUgYXJlIHNvbWUgZnJvZyBzcGVjaWVzIGZvdW5kIG1vdmluZyBkdXJpbmcgdGhlIGRheS4gVGhlIHdhdGVyIGh5ZHJpYyBwYXJhbWV0ZXJzIChlLmcuIHNraW4gcmVzaXN0YW5jZSwgd2F0ZXIgdXB0YWtlIHJhdGUsIGRlaHlkcmF0aW9uIHRvbGVyYW5jZSkgd2VyZSBiYXNlZCBvbiB0aGUgYXZlcmFnZSB2YWx1ZXMgb2YgdGhlIGRhdGFzZXQgY29sbGVjdGVkIGZyb20gdGhlIFBSSVNNQSBzZWFyY2guIFRoZSB0aGVybWFsIHBhcmFtZXRlcnMgKG1pbmltdW0gYW5kIG1heGltdW0gZm9yYWdpbmcgYW5kIGNyaXRpY2FsIHRlbXBlcmF0dXJlKSB3ZXJlIGJhc2VkIG9uICpSaGluYWxsYSBtYXJpbmEqIHdoaWNoIGhhcyBiZWVuIHZlcmlmaWVkIGluIEBLZWFybmV5MjAwOC4KClRocmVlIHdhdGVyLXNhdmluZyBzdHJhdGVnaWVzIHdlcmUgY29uc3RydWN0ZWQgdG8gYnJvYWRseSByZWZsZWN0IGVhY2ggZWNvdHlwZSB0aGF0IHVzZSBlaXRoZXIgYmVoYXZpb3VyYWwgc3RyYXRlZ2llcyBzdWNoIGFzIG1pY3JvaGFiaXRhdCBzZWxlY3Rpb24sIG9yIHBoeXNpb2xvZ2ljYWwgc3RyYXRlZ2llcyBzdWNoIGFzIGluY3JlYXNlZCBza2luIHJlc2lzdGFuY2Ugb3Igc2tpbiB0aGlja25lc3MgKCoqVGFibGUgUzUqKikuIEZvciBleGFtcGxlLCBtYW55IGFtcGhpYmlhbnMgKGVzcGljYWxseSBhcmlkIHNwZWNpYWxpc3QpIHNlZWsgb3IgYnVycm93IHVuZGVyZ3JvdW5kIHRvIHJlZ3VsYXRlIGJvZHkgdGVtcGVyYXR1cmUgYW5kIHdhdGVyIGJhbGFuY2Ugd2l0aG91dCBleGhpYml0aW5nIHRoaWNrZXIgc2tpbiBvciBoaWdoZXIgc2tpbiByZXNpc3RhbmNlLiBUaGlzIGlzIGJlY2F1c2UgdW5kZXJncm91bmQgYnVycm93cyBhcmUgZ2VuZXJhbGx5IGNvb2xlciwgbGVzcyB2YXJpZWQgdGVtcGVyYXR1cmUgZmx1Y3R1YXRpb24sIGFuZCBtb3JlIG1vaXN0IHJlbGF0aXZlIHRvIHRoZSBzdXJmYWNlIGNsaW1hdGUuIAoKKipUYWJsZSBTNS4qKiBNb2RpZmllZCBwYXJhbWV0ZXJzIGZvciB0aGUgYHNpbS5lY3RvYCBmdW5jdGlvbiBmb3IgZWFjaCBoeXBvdGhldGljYWwgZnJvZyBtb2RlbC4gVGhlIHNraW4gcmVzaXN0YW5jZSB2YWx1ZXMgd2VyZSBiYXNlZCBvbiB0aGUgYXZlcmFnZSBlbXBpcmljYWwgbWVhc3VyZW1lbnRzIGZvciBhIHR5cGljYWwgZnJvZyBhbmQgYSB3YXRlcnByb29mIGZyb2cgaW4gdGhlIG1ldGEtYW5hbHlzaXMuIFNlZWsgc2hhZGUgcmVwcmVzZW50cyBtaWNyb2NsaW1hdGUgc2ltdWxhdGVkIHVuZGVyIHNoYWRlZCBjb25kaXRpb25zICgwLTkwJSBzaGFkZSkuIFJldHJlYXQgdW5kZXJncm91bmQgcmVwcmVzZW50cyB0aGUgYWJpbGl0eSBmb3IgdGhlIGZyb2cgdG8gc2VlayBzdWl0YWJsZSBtaWNyb2NsaW1hdGVzIHVuZGVyZ3JvdW5kLiBDYW4gY2xpbWIgcmVwcmVzZW50cyB0aGUgYWJpbGl0eSBmb3IgdGhlIGZyb2cgdG8gc2VlayBzdWl0YWJsZSBtaWNyb2NsaW1hdGVzIGFib3ZlIGdyb3VuZCBsZXZlbCAoZS5nLiB0cmVlcywgY2xpZmZzKS4gTm90ZSwgZnJvZ3MgYXJlIG5vdCBhY3RpdmUgd2hlbiB1bmRlcmdyb3VuZCwgYW5kIHdhdGVyIHVwdGFrZSBvbmx5IG9jY3VycyBkdXJpbmcgaW5hY3Rpdml0eS4KCmBgYHtyIHRhYmxlIFM1LCBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQpkYXRhLmZyYW1lKHN0cmF0ZWd5ID0gYygiU2hhZGUgb25seSIsICJXYXRlcnByb29mIiwiRm9zc29yaWFsIiksIAogICAgICAgICAgIHNraW4gPSBjKCJMb3ciLCAiSGlnaCIsICJMb3ciKSwKICAgICAgICAgICBzaGFkZSA9IGMoIlllcyIsICJZZXMiLCAiWWVzIiksCiAgICAgICAgICAgdW5kZXJncm91bmQgPSBjKCJObyIsICJObyIsICJZZXMiKSwKICAgICAgICAgICBjbGltYiA9IGMoIk5vIiwgIlllcyIsICJObyIpLAogICAgICAgICAgIGVjb3R5cGUgPSBjKCJHcm91bmQtZHdlbGxpbmciLCAiQXJib3JlYWwiLCAiRm9zc29yaWFsIikpICU+JQogIGtuaXRyOjprYWJsZShjb2wubmFtZXMgPSBjKCJXYXRlci1zYXZpbmcgc3RyYXRlZ3kiLCAiU2tpbiByZXNpc3RhbmNlIiwgIlNlZWsgc2hhZGU/IiwgIlJldHJlYXQgdW5kZXJncm91bmQ/IiwgIkNhbiBjbGltYj8iLCAiRWNvdHlwZSIpKSAKYGBgCgpJdCBpcyBpbXBvcnRhbnQgdG8gbm90ZSB0aGF0IHdlIGZvY3VzIG9ubHkgb24gdGhlIGRpcmVjdCBlZmZlY3RzIG9mIGVudmlyb25tZW50YWwgY2hhbmdlIG9uIHdhdGVyIGJ1ZGdldHMgYnkgcHJlZGljdGluZyBjaGFuZ2VzIGluIEVXTCByYXRlcy4gVGhlIGNvbmNsdXNpb25zIHdlIGRyYXcgZG8gbm90IGFjY291bnQgZm9yIHRoZSBpbmRpcmVjdCBlZmZlY3RzIG9mIGVudmlyb25tZW50YWwgY2hhbmdlIG9uIHdhdGVyIGJ1ZGdldHMsIHN1Y2ggYXMgcG90ZW50aWFsIGNoYW5nZXMgdG8gdGhlcm1hbCB0b2xlcmFuY2UgYXMgYSByZXN1bHQgb2YgZGVoeWRyYXRpb24sIG9yIHRoZSB0aGVybW9yZWd1bGF0b3J5IGRpZmZpY3VsdGllcyB0aGF0IG1heSBhcmlzZSBhcyBhIHJlc3VsdCBvZiBoYWJpdGF0IG1vZGlmaWNhdGlvbi4KCmBgYHtyIGZyb2dfc2ltLCBtZXNzYWdlPUZBTFNFLCBjYWNoZT1UUlVFLCByZXN1bHRzPSJoaWRlIn0Kc291cmNlKCIvVXNlcnMvbmljaG9sYXN3dS9MaWJyYXJ5L0Nsb3VkU3RvcmFnZS9PbmVEcml2ZS1XZXN0ZXJuU3lkbmV5VW5pdmVyc2l0eS9Ecm91Z2h0IHByb2plY3QvY29kZS9iZWhhdl9mdW5jdGlvbnMuUiIpCiMgQ29uc3RydWN0IGZyb2cgbW9kZWwKIyBjb21wdXRlIHRoZSBoZWF0IGV4Y2hhbmdlIGJ5IGNvbnZlY3Rpb24gKGV4dHJhY3QgbWFzcyB0cmFuc2ZlciBjb2VmZmljaWVudCwgUHJhbmR0bCBudW1iZXIgYW5kIFNjaG1pZHQgbnVtYmVyKQpDT05WX291dCA8LSBOaWNoZU1hcFI6OkNPTlZfRU5ETyhUUyAgICAgPSAxOSwgIyBza2luIHRlbXBlcmF0dXJlICjCsEMpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRFTlYgICA9IDIwLCAjIGZsdWlkIHRlbXBlcmF0dXJlICjCsEMpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNIQVBFICA9IDQsICMgNCBpcyBlbGxpcHNvaWQKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU1VSRkFSID0gbWVhbihyZXNpc3RfZGF0JGRvcnNfU0FfY20yLCBuYS5ybSA9IFRSVUUpIC8gMTAwMDAsICAjIHN1cmZhY2UgYXJlYSBmb3IgY29udmVjdGlvbiwgbTIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRkxUWVBFID0gMCwgIyBmbHVpZCB0eXBlOiAwID0gYWlyCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZVUlRTVCA9IDAsICMgdGVzdCBvZiBwcmVzZW5jZSBvZiBmdXIgKGxlbmd0aCB4IGRpYW1ldGVyIHggZGVuc2l0eSB4IGRlcHRoKSAoLSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRCAgICAgID0gbWVhbihyZXNpc3RfZGF0JEQsIG5hLnJtID0gVFJVRSksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBURkEgICAgPSAyMCwgIyBpbml0aWFsIGZ1ci9haXIgaW50ZXJmYWNlIHRlbXBlcmF0dXJlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFZFTCAgICA9IG1lYW4ocmVzaXN0X2RhdCRhaXJmbG93X2NtX3MsIG5hLnJtID0gVFJVRSkgLyAxMDAsICMgd2luZCBzcGVlZCAobS9zKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBaRlVSICAgPSAwLCAjIGZ1ciBkZXB0aCwgbWVhbiAobSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQlAgICAgID0gMTAxMzI1LCAjIGJhcm9tZXRyaWMgcHJlc3N1cmUgYXQgc2VhIGxldmVsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEVMRVYgICA9IDApICMgZWxldmF0aW9uIChtKQoKIyBiYXNpYyBwYXJhbWV0ZXJzIGZvciAzMCBnIGZyb2cKV3dfZyAgICAgICAgIDwtIGV4cChtZWFuKGxvZyhyYXdfZGF0JG1lYW5fbWFzc19nKSwgbmEucm0gPSBUUlVFKSkgIyBnZW9tZXRyaWMgbWVhbiB3ZXQgd2VpZ2h0IG9mIGFuaW1hbCAoZyksIGFjY291bnQgZm9yIHVuZXZlbiBkaXN0cmlidXRpb24Kcl9zX2xvdyAgICAgIDwtIHJlc2lzdF9kYXQgJT4lIGRwbHlyOjpmaWx0ZXIoc3RyYXRlZ3kgPT0gIm5vbmUiKSAlPiUgZHBseXI6OnNlbGVjdCh1bml0X2NvcnJlY3RlZF9tZWFuKSAjIHNraW4gcmVzaXN0YW5jZQpwY3Rfd2V0X2hpZ2ggPC0gMSAvIChDT05WX291dFs1XSAqIG1lYW4ocl9zX2xvdyR1bml0X2NvcnJlY3RlZF9tZWFuKSArIChDT05WX291dFsxMV0gLyBDT05WX291dFsxM10pIF4gMC42NjY2NjY2KSAqIDEwMCAgIyAlIG9mIHN1cmZhY2UgYXJlYSBhY3RpbmcgYXMgYSBmcmVlLXdhdGVyIGV4Y2hhbmdlciAoUGlydGxlIGV0IGFsIDIwMTcpCgojIHBhcmFtZXRlcnMgZm9yIGEgd2F0ZXItcHJvb2YgZnJvZwpyX3NfaGlnaCAgICA8LSByZXNpc3RfZGF0ICU+JSBkcGx5cjo6ZmlsdGVyKHN0cmF0ZWd5ID09ICJ3YXRlci1wcm9vZiIpICU+JSBkcGx5cjo6c2VsZWN0KHVuaXRfY29ycmVjdGVkX21lYW4pICMgc2tpbiByZXNpc3RhbmNlCnBjdF93ZXRfbG93IDwtIDEgLyAoQ09OVl9vdXRbNV0gKiBtYXgocl9zX2hpZ2gkdW5pdF9jb3JyZWN0ZWRfbWVhbikgKyAoQ09OVl9vdXRbMTFdIC8gQ09OVl9vdXRbMTNdKSBeIDAuNjY2NjY2NikgKiAxMDAgIyAlIG9mIHN1cmZhY2UgYXJlYSBhY3RpbmcgYXMgYSBmcmVlLXdhdGVyIGV4Y2hhbmdlciAoUGlydGxlIGV0IGFsIDIwMTcpCgojIFRoZXJtYWwgdHJhaXRzIGJhc2VkIG9uIFJoaW5lbGxhIG1hcmluYQpUbWluICAgPC0gMTMuNyAjIG1pbmltdW0gVGIgYXQgd2hpY2ggYWN0aXZpdHkgb2NjdXJzIChLZWFybmV5IGV0IGFsIDIwMDgpClRtYXggICA8LSAzMC40ICMgbWF4aW11bSBUYiBhdCB3aGljaCBhY3Rpdml0eSBvY2N1cnMgKEtlYXJuZXkgZXQgYWwgMjAwOCkKI1RfcHJlZiA8LSAyNCAjIHByZWZlcnJlZCBUYiAoS2Vhcm5leSBldCBhbCAyMDA4KQpDVG1heCAgPC0gMzcgIyBjcml0aWNhbCB0aGVybWFsIG1pbmltdW0gKGFmZmVjdHMgY2hvaWNlIG9mIHJldHJlYXQpIFRyYWN5IGV0IGFsIDIwMTIKQ1RtaW4gIDwtIDggIyBjcml0aWNhbCB0aGVybWFsIG1heGltdW0gKGFmZmVjdHMgY2hvaWNlIG9mIHJldHJlYXQpIEtvbGJlIGV0IGFsIDIwMTAsIE1jQ2FubiBldCBhbCAyMDE0CgojIFdhdGVyIGJhbGFuY2UgdHJhaXRzCm1pbl9oeWQgPC0gODAgIyBtaW5pbXVtIHRvbGVyYXRlZCBoeWRyYXRpb24gYmVmb3JlIGFjdGl2aXR5IGRlY2xpbmVzICglIG9mIGZ1bGx5IGh5ZHJhdGVkIGFuaW1hbHMpCmh5ZC5kZWF0aCA8LSA1MCAjIG1pbmltdW0gdG9sZXJhdGVkIGh5ZHJhdGlvbiBiZWZvcmUgZGVhdGggKCUgb2YgZnVsbHkgaHlkcmF0ZWQgYW5pbWFscykKd3VfcmF0ZSA8LSB3dV9kYXQgJT4lIGRwbHlyOjpmaWx0ZXIoc3RyYXRlZ3kgPT0gIm5vbmUiKSAlPiUgZHBseXI6OnNlbGVjdChtZ19oX21lYW4pCmh5ZF9yYXRlIDwtIGV4cChtZWFuKGxvZyh3dV9yYXRlJG1nX2hfbWVhbiksIG5hLnJtID0gVFJVRSkpIC8gMTAwMCAjIGdlb21ldHJpYyBtZWFuIHJlaHlkcmF0aW9uIHJhdGUgKGcvaCksIGFjY291bnQgZm9yIHVuZXZlbiBkaXN0cmlidXRpb24KIyBkZXBlbmRzIG9uIGN1cnJlbnQgYW5kIG1heCBoeWRyYXRpb24gbGlrZSB0aGlzOiBoeWQucmF0ZSAqICgoaHlkIC0gaHlkLmN1cnJlbnQpIC8gaHlkKQoKIyBiZWhhdiA9ICdkaXVybmFsJywgJ25vY3R1cm5hbCcgb3IgJ2JvdGgnCiMgd2F0ZXI7IGRvZXMgdGhlIGZyb2cgc2VsZWN0IGRlcHRoIGFjY29yZGluZyB0byB3YXRlciBwb3RlbnRpYWw/IChUUlVFIG9yIEZBTFNFKQojIHdhdGVyLmFjdDsgZG9lcyB0aGUgYWN0aXZpdHkgZGVwZW5kIG9uIHdhdGVyIGxvc3M/IChUUlVFIG9yIEZBTFNFKQoKIyBTSEFERSBNT0RFTApzaGFkX2N1cnJfd2V0X21vZCA8LSBzaW0uZWN0byhtaWNyb19jdXJyX3dldCwgV3dfZyA9IFd3X2csIHNoYXBlID0gNCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRtYXggPSBUbWF4LCBUbWluID0gVG1pbiwgQ1RtaW4gPSBDVG1pbiwgQ1RtYXggPSBDVG1heCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYmVoYXYgPSAnYm90aCcsIGluLnNoYWRlID0gVFJVRSwgYnVycm93ID0gRkFMU0UsIGNsaW1iID0gRkFMU0UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1pbi5oeWQgPSBtaW5faHlkLCBoeWQuZGVhdGggPSBoeWQuZGVhdGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGh5ZC5yYXRlID0gaHlkX3JhdGUsIHBjdF93ZXQgPSBwY3Rfd2V0X2hpZ2gsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3YXRlciA9IEZBTFNFLCB3YXRlci5hY3QgPSBUUlVFKQoKc2hhZF9jdXJyX2RyeV9tb2QgPC0gc2ltLmVjdG8obWljcm9fY3Vycl9kcnksIFd3X2cgPSBXd19nLCBzaGFwZSA9IDQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUbWF4ID0gVG1heCwgVG1pbiA9IFRtaW4sIENUbWluID0gQ1RtaW4sIENUbWF4ID0gQ1RtYXgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJlaGF2ID0gJ2JvdGgnLCBpbi5zaGFkZSA9IFRSVUUsIGJ1cnJvdyA9IEZBTFNFLCBjbGltYiA9IEZBTFNFLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtaW4uaHlkID0gbWluX2h5ZCwgaHlkLmRlYXRoID0gaHlkLmRlYXRoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoeWQucmF0ZSA9IGh5ZF9yYXRlLCBwY3Rfd2V0ID0gcGN0X3dldF9oaWdoLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2F0ZXIgPSBGQUxTRSwgd2F0ZXIuYWN0ID0gVFJVRSkKCnNoYWRfd2FybV93ZXRfbW9kIDwtIHNpbS5lY3RvKG1pY3JvX3dhcm1fd2V0LCBXd19nID0gV3dfZywgc2hhcGUgPSA0LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVG1heCA9IFRtYXgsIFRtaW4gPSBUbWluLCBDVG1pbiA9IENUbWluLCBDVG1heCA9IENUbWF4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiZWhhdiA9ICdib3RoJywgaW4uc2hhZGUgPSBUUlVFLCBidXJyb3cgPSBGQUxTRSwgY2xpbWIgPSBGQUxTRSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWluLmh5ZCA9IG1pbl9oeWQsIGh5ZC5kZWF0aCA9IGh5ZC5kZWF0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaHlkLnJhdGUgPSBoeWRfcmF0ZSwgcGN0X3dldCA9IHBjdF93ZXRfaGlnaCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdhdGVyID0gRkFMU0UsIHdhdGVyLmFjdCA9IFRSVUUpCgpzaGFkX3dhcm1fZHJ5X21vZCA8LSBzaW0uZWN0byhtaWNyb193YXJtX2RyeSwgV3dfZyA9IFd3X2csIHNoYXBlID0gNCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRtYXggPSBUbWF4LCBUbWluID0gVG1pbiwgQ1RtaW4gPSBDVG1pbiwgQ1RtYXggPSBDVG1heCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYmVoYXYgPSAnYm90aCcsIGluLnNoYWRlID0gVFJVRSwgYnVycm93ID0gRkFMU0UsIGNsaW1iID0gRkFMU0UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1pbi5oeWQgPSBtaW5faHlkLCBoeWQuZGVhdGggPSBoeWQuZGVhdGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGh5ZC5yYXRlID0gaHlkX3JhdGUsIHBjdF93ZXQgPSBwY3Rfd2V0X2hpZ2gsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3YXRlciA9IEZBTFNFLCB3YXRlci5hY3QgPSBUUlVFKQoKIyBXQVRFUi1QUk9PRiBNT0RFTAp0cmVlX2N1cnJfd2V0X21vZCA8LSBzaW0uZWN0byhtaWNyb19jdXJyX3dldCwgV3dfZyA9IFd3X2csIHNoYXBlID0gNCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRtYXggPSBUbWF4LCBUbWluID0gVG1pbiwgQ1RtaW4gPSBDVG1pbiwgQ1RtYXggPSBDVG1heCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYmVoYXYgPSAnYm90aCcsIGluLnNoYWRlID0gVFJVRSwgYnVycm93ID0gRkFMU0UsIGNsaW1iID0gVFJVRSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWluLmh5ZCA9IG1pbl9oeWQsIGh5ZC5kZWF0aCA9IGh5ZC5kZWF0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaHlkLnJhdGUgPSBoeWRfcmF0ZSwgcGN0X3dldCA9IHBjdF93ZXRfbG93LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2F0ZXIgPSBUUlVFLCB3YXRlci5hY3QgPSBUUlVFKQoKdHJlZV9jdXJyX2RyeV9tb2QgPC0gc2ltLmVjdG8obWljcm9fY3Vycl9kcnksIFd3X2cgPSBXd19nLCBzaGFwZSA9IDQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUbWF4ID0gVG1heCwgVG1pbiA9IFRtaW4sIENUbWluID0gQ1RtaW4sIENUbWF4ID0gQ1RtYXgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJlaGF2ID0gJ2JvdGgnLCBpbi5zaGFkZSA9IFRSVUUsIGJ1cnJvdyA9IEZBTFNFLCBjbGltYiA9IFRSVUUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1pbi5oeWQgPSBtaW5faHlkLCBoeWQuZGVhdGggPSBoeWQuZGVhdGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGh5ZC5yYXRlID0gaHlkX3JhdGUsIHBjdF93ZXQgPSBwY3Rfd2V0X2xvdywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdhdGVyID0gVFJVRSwgd2F0ZXIuYWN0ID0gVFJVRSkKCnRyZWVfd2FybV93ZXRfbW9kIDwtIHNpbS5lY3RvKG1pY3JvX3dhcm1fd2V0LCBXd19nID0gV3dfZywgc2hhcGUgPSA0LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVG1heCA9IFRtYXgsIFRtaW4gPSBUbWluLCBDVG1pbiA9IENUbWluLCBDVG1heCA9IENUbWF4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiZWhhdiA9ICdib3RoJywgaW4uc2hhZGUgPSBUUlVFLCBidXJyb3cgPSBGQUxTRSwgY2xpbWIgPSBUUlVFLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtaW4uaHlkID0gbWluX2h5ZCwgaHlkLmRlYXRoID0gaHlkLmRlYXRoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoeWQucmF0ZSA9IGh5ZF9yYXRlLCBwY3Rfd2V0ID0gcGN0X3dldF9sb3csIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3YXRlciA9IFRSVUUsIHdhdGVyLmFjdCA9IFRSVUUpCgp0cmVlX3dhcm1fZHJ5X21vZCA8LSBzaW0uZWN0byhtaWNyb193YXJtX2RyeSwgV3dfZyA9IFd3X2csIHNoYXBlID0gNCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRtYXggPSBUbWF4LCBUbWluID0gVG1pbiwgQ1RtaW4gPSBDVG1pbiwgQ1RtYXggPSBDVG1heCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYmVoYXYgPSAnYm90aCcsIGluLnNoYWRlID0gVFJVRSwgYnVycm93ID0gRkFMU0UsIGNsaW1iID0gVFJVRSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWluLmh5ZCA9IG1pbl9oeWQsIGh5ZC5kZWF0aCA9IGh5ZC5kZWF0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaHlkLnJhdGUgPSBoeWRfcmF0ZSwgcGN0X3dldCA9IHBjdF93ZXRfbG93LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2F0ZXIgPSBUUlVFLCB3YXRlci5hY3QgPSBUUlVFKQoKIyBCVVJST1dJTkcgTU9ERUwKYnVycl9jdXJyX3dldF9tb2QgPC0gc2ltLmVjdG8obWljcm9fY3Vycl93ZXQsIFd3X2cgPSBXd19nLCBzaGFwZSA9IDQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUbWF4ID0gVG1heCwgVG1pbiA9IFRtaW4sIENUbWluID0gQ1RtaW4sIENUbWF4ID0gQ1RtYXgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJlaGF2ID0gJ2JvdGgnLCBpbi5zaGFkZSA9IFRSVUUsIGJ1cnJvdyA9IFRSVUUsIGNsaW1iID0gRkFMU0UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1pbi5oeWQgPSBtaW5faHlkLCBoeWQuZGVhdGggPSBoeWQuZGVhdGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGh5ZC5yYXRlID0gaHlkX3JhdGUsIHBjdF93ZXQgPSBwY3Rfd2V0X2hpZ2gsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3YXRlciA9IFRSVUUsIHdhdGVyLmFjdCA9IFRSVUUpCgpidXJyX2N1cnJfZHJ5X21vZCA8LSBzaW0uZWN0byhtaWNyb19jdXJyX2RyeSwgV3dfZyA9IFd3X2csIHNoYXBlID0gNCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRtYXggPSBUbWF4LCBUbWluID0gVG1pbiwgQ1RtaW4gPSBDVG1pbiwgQ1RtYXggPSBDVG1heCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYmVoYXYgPSAnYm90aCcsIGluLnNoYWRlID0gVFJVRSwgYnVycm93ID0gVFJVRSwgY2xpbWIgPSBGQUxTRSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWluLmh5ZCA9IG1pbl9oeWQsIGh5ZC5kZWF0aCA9IGh5ZC5kZWF0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaHlkLnJhdGUgPSBoeWRfcmF0ZSwgcGN0X3dldCA9IHBjdF93ZXRfaGlnaCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdhdGVyID0gVFJVRSwgd2F0ZXIuYWN0ID0gVFJVRSkKCmJ1cnJfd2FybV93ZXRfbW9kIDwtIHNpbS5lY3RvKG1pY3JvX3dhcm1fd2V0LCBXd19nID0gV3dfZywgc2hhcGUgPSA0LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVG1heCA9IFRtYXgsIFRtaW4gPSBUbWluLCBDVG1pbiA9IENUbWluLCBDVG1heCA9IENUbWF4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiZWhhdiA9ICdib3RoJywgaW4uc2hhZGUgPSBUUlVFLCBidXJyb3cgPSBUUlVFLCBjbGltYiA9IEZBTFNFLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtaW4uaHlkID0gbWluX2h5ZCwgaHlkLmRlYXRoID0gaHlkLmRlYXRoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoeWQucmF0ZSA9IGh5ZF9yYXRlLCBwY3Rfd2V0ID0gcGN0X3dldF9oaWdoLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2F0ZXIgPSBUUlVFLCB3YXRlci5hY3QgPSBUUlVFKQoKYnVycl93YXJtX2RyeV9tb2QgPC0gc2ltLmVjdG8obWljcm9fd2FybV9kcnksIFd3X2cgPSBXd19nLCBzaGFwZSA9IDQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUbWF4ID0gVG1heCwgVG1pbiA9IFRtaW4sIENUbWluID0gQ1RtaW4sIENUbWF4ID0gQ1RtYXgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJlaGF2ID0gJ2JvdGgnLCBpbi5zaGFkZSA9IFRSVUUsIGJ1cnJvdyA9IFRSVUUsIGNsaW1iID0gRkFMU0UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1pbi5oeWQgPSBtaW5faHlkLCBoeWQuZGVhdGggPSBoeWQuZGVhdGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGh5ZC5yYXRlID0gaHlkX3JhdGUsIHBjdF93ZXQgPSBwY3Rfd2V0X2hpZ2gsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3YXRlciA9IFRSVUUsIHdhdGVyLmFjdCA9IFRSVUUpCmBgYAoKCmBgYCB7ciBhY3RpdmV9CiMgU0hBREUgTU9ERUwKc2hhZF9jdXJyX3dldF9kZiA8LSBkYXRhLmZyYW1lKHNoYWRfY3Vycl93ZXRfbW9kJGFjdCkgJT4lCiAgdGliYmxlOjpyb3dpZF90b19jb2x1bW4oImhvdXIiKSAlPiUKICBkcGx5cjo6cmVuYW1lKGFjdGl2ZSA9IHNoYWRfY3Vycl93ZXRfbW9kLmFjdCkgJT4lCiAgZHBseXI6Om11dGF0ZShkYXkgPSBjZWlsaW5nKDE6ODc2MC8yNCkpICU+JQogIGRwbHlyOjpncm91cF9ieShkYXkpICU+JQogIGRwbHlyOjpzdW1tYXJpc2UoY3Vycl93ZXQgPSBsZW5ndGgoYWN0aXZlW2FjdGl2ZSA9PSBUUlVFXSkpCgpzaGFkX2N1cnJfZHJ5X2RmIDwtIGRhdGEuZnJhbWUoc2hhZF9jdXJyX2RyeV9tb2QkYWN0KSAlPiUKICB0aWJibGU6OnJvd2lkX3RvX2NvbHVtbigiaG91ciIpICU+JQogIGRwbHlyOjpyZW5hbWUoYWN0aXZlID0gc2hhZF9jdXJyX2RyeV9tb2QuYWN0KSAlPiUKICBkcGx5cjo6bXV0YXRlKGRheSA9IGNlaWxpbmcoMTo4NzYwLzI0KSkgJT4lCiAgZHBseXI6Omdyb3VwX2J5KGRheSkgJT4lCiAgZHBseXI6OnN1bW1hcmlzZShjdXJyX2RyeSA9IGxlbmd0aChhY3RpdmVbYWN0aXZlID09IFRSVUVdKSkKCnNoYWRfd2FybV93ZXRfZGYgPC0gZGF0YS5mcmFtZShzaGFkX3dhcm1fd2V0X21vZCRhY3QpICU+JQogIHRpYmJsZTo6cm93aWRfdG9fY29sdW1uKCJob3VyIikgJT4lCiAgZHBseXI6OnJlbmFtZShhY3RpdmUgPSBzaGFkX3dhcm1fd2V0X21vZC5hY3QpICU+JQogIGRwbHlyOjptdXRhdGUoZGF5ID0gY2VpbGluZygxOjg3NjAvMjQpKSAlPiUKICBkcGx5cjo6Z3JvdXBfYnkoZGF5KSAlPiUKICBkcGx5cjo6c3VtbWFyaXNlKHdhcm1fd2V0ID0gbGVuZ3RoKGFjdGl2ZVthY3RpdmUgPT0gVFJVRV0pKQoKc2hhZF93YXJtX2RyeV9kZiA8LSBkYXRhLmZyYW1lKHNoYWRfd2FybV9kcnlfbW9kJGFjdCkgJT4lCiAgdGliYmxlOjpyb3dpZF90b19jb2x1bW4oImhvdXIiKSAlPiUKICBkcGx5cjo6cmVuYW1lKGFjdGl2ZSA9IHNoYWRfd2FybV9kcnlfbW9kLmFjdCkgJT4lCiAgZHBseXI6Om11dGF0ZShkYXkgPSBjZWlsaW5nKDE6ODc2MC8yNCkpICU+JQogIGRwbHlyOjpncm91cF9ieShkYXkpICU+JQogIGRwbHlyOjpzdW1tYXJpc2Uod2FybV9kcnkgPSBsZW5ndGgoYWN0aXZlW2FjdGl2ZSA9PSBUUlVFXSkpCgpzaGFkX21vZGVsIDwtIHNoYWRfY3Vycl93ZXRfZGYgJT4lCiAgbWVyZ2Uoc2hhZF9jdXJyX2RyeV9kZiwgYnkgPSAiZGF5IikgJT4lCiAgbWVyZ2Uoc2hhZF93YXJtX3dldF9kZiwgYnkgPSAiZGF5IikgJT4lCiAgbWVyZ2Uoc2hhZF93YXJtX2RyeV9kZiwgYnkgPSAiZGF5IikgJT4lCiAgcGl2b3RfbG9uZ2VyKCFkYXksIG5hbWVzX3RvID0gImNvbmRpdGlvbiIsIHZhbHVlc190byA9ICJob3VycyIpICU+JQogIGRwbHlyOjptdXRhdGUoY29uZGl0aW9uID0gZmFjdG9yKGNvbmRpdGlvbiwgbGV2ZWxzID0gYygid2FybV9kcnkiLCAid2FybV93ZXQiLCAiY3Vycl9kcnkiLCAiY3Vycl93ZXQiKSksCiAgICAgICAgICAgICAgICBzZWFzb24gPSBjYXNlX3doZW4oCiAgICBkYXkgPj0gMzM1IH4gInN1bW1lciIsCiAgICBkYXkgPj0gMSAmIGRheSA8PSA2MSB+ICJzdW1tZXIiLAogICAgZGF5ID49IDYyICYgZGF5IDw9IDE1MyB+ICJhdXR1bW4iLAogICAgZGF5ID49IDE1NCAmIGRheSA8PSAyNDQgfiAid2ludGVyIiwKICAgIGRheSA+PSAyNDUgJiBkYXkgPD0gMzM0IH4gInNwcmluZyIKICAgICkpCgojIFRSRUUgTU9ERUwKdHJlZV9jdXJyX3dldF9kZiA8LSBkYXRhLmZyYW1lKHRyZWVfY3Vycl93ZXRfbW9kJGFjdCkgJT4lCiAgdGliYmxlOjpyb3dpZF90b19jb2x1bW4oImhvdXIiKSAlPiUKICBkcGx5cjo6cmVuYW1lKGFjdGl2ZSA9IHRyZWVfY3Vycl93ZXRfbW9kLmFjdCkgJT4lCiAgZHBseXI6Om11dGF0ZShkYXkgPSBjZWlsaW5nKDE6ODc2MC8yNCkpICU+JQogIGRwbHlyOjpncm91cF9ieShkYXkpICU+JQogIGRwbHlyOjpzdW1tYXJpc2UoY3Vycl93ZXQgPSBsZW5ndGgoYWN0aXZlW2FjdGl2ZSA9PSBUUlVFXSkpCgp0cmVlX2N1cnJfZHJ5X2RmIDwtIGRhdGEuZnJhbWUodHJlZV9jdXJyX2RyeV9tb2QkYWN0KSAlPiUKICB0aWJibGU6OnJvd2lkX3RvX2NvbHVtbigiaG91ciIpICU+JQogIGRwbHlyOjpyZW5hbWUoYWN0aXZlID0gdHJlZV9jdXJyX2RyeV9tb2QuYWN0KSAlPiUKICBkcGx5cjo6bXV0YXRlKGRheSA9IGNlaWxpbmcoMTo4NzYwLzI0KSkgJT4lCiAgZHBseXI6Omdyb3VwX2J5KGRheSkgJT4lCiAgZHBseXI6OnN1bW1hcmlzZShjdXJyX2RyeSA9IGxlbmd0aChhY3RpdmVbYWN0aXZlID09IFRSVUVdKSkKCnRyZWVfd2FybV93ZXRfZGYgPC0gZGF0YS5mcmFtZSh0cmVlX3dhcm1fd2V0X21vZCRhY3QpICU+JQogIHRpYmJsZTo6cm93aWRfdG9fY29sdW1uKCJob3VyIikgJT4lCiAgZHBseXI6OnJlbmFtZShhY3RpdmUgPSB0cmVlX3dhcm1fd2V0X21vZC5hY3QpICU+JQogIGRwbHlyOjptdXRhdGUoZGF5ID0gY2VpbGluZygxOjg3NjAvMjQpKSAlPiUKICBkcGx5cjo6Z3JvdXBfYnkoZGF5KSAlPiUKICBkcGx5cjo6c3VtbWFyaXNlKHdhcm1fd2V0ID0gbGVuZ3RoKGFjdGl2ZVthY3RpdmUgPT0gVFJVRV0pKQoKdHJlZV93YXJtX2RyeV9kZiA8LSBkYXRhLmZyYW1lKHRyZWVfd2FybV9kcnlfbW9kJGFjdCkgJT4lCiAgdGliYmxlOjpyb3dpZF90b19jb2x1bW4oImhvdXIiKSAlPiUKICBkcGx5cjo6cmVuYW1lKGFjdGl2ZSA9IHRyZWVfd2FybV9kcnlfbW9kLmFjdCkgJT4lCiAgZHBseXI6Om11dGF0ZShkYXkgPSBjZWlsaW5nKDE6ODc2MC8yNCkpICU+JQogIGRwbHlyOjpncm91cF9ieShkYXkpICU+JQogIGRwbHlyOjpzdW1tYXJpc2Uod2FybV9kcnkgPSBsZW5ndGgoYWN0aXZlW2FjdGl2ZSA9PSBUUlVFXSkpCgp0cmVlX21vZGVsIDwtIHRyZWVfY3Vycl93ZXRfZGYgJT4lCiAgbWVyZ2UodHJlZV9jdXJyX2RyeV9kZiwgYnkgPSAiZGF5IikgJT4lCiAgbWVyZ2UodHJlZV93YXJtX3dldF9kZiwgYnkgPSAiZGF5IikgJT4lCiAgbWVyZ2UodHJlZV93YXJtX2RyeV9kZiwgYnkgPSAiZGF5IikgJT4lCiAgcGl2b3RfbG9uZ2VyKCFkYXksIG5hbWVzX3RvID0gImNvbmRpdGlvbiIsIHZhbHVlc190byA9ICJob3VycyIpICU+JQogIGRwbHlyOjptdXRhdGUoY29uZGl0aW9uID0gZmFjdG9yKGNvbmRpdGlvbiwgbGV2ZWxzID0gYygid2FybV9kcnkiLCAid2FybV93ZXQiLCAiY3Vycl9kcnkiLCAiY3Vycl93ZXQiKSksCiAgICAgICAgICAgICAgICBzZWFzb24gPSBjYXNlX3doZW4oCiAgICBkYXkgPj0gMzM1IH4gInN1bW1lciIsCiAgICBkYXkgPj0gMSAmIGRheSA8PSA2MSB+ICJzdW1tZXIiLAogICAgZGF5ID49IDYyICYgZGF5IDw9IDE1MyB+ICJhdXR1bW4iLAogICAgZGF5ID49IDE1NCAmIGRheSA8PSAyNDQgfiAid2ludGVyIiwKICAgIGRheSA+PSAyNDUgJiBkYXkgPD0gMzM0IH4gInNwcmluZyIKICAgICkpCgojIEZPU1NPUklBTCBNT0RFTApidXJyX2N1cnJfd2V0X2RmIDwtIGRhdGEuZnJhbWUoYnVycl9jdXJyX3dldF9tb2QkYWN0KSAlPiUKICB0aWJibGU6OnJvd2lkX3RvX2NvbHVtbigiaG91ciIpICU+JQogIGRwbHlyOjpyZW5hbWUoYWN0aXZlID0gYnVycl9jdXJyX3dldF9tb2QuYWN0KSAlPiUKICBkcGx5cjo6bXV0YXRlKGRheSA9IGNlaWxpbmcoMTo4NzYwLzI0KSkgJT4lCiAgZHBseXI6Omdyb3VwX2J5KGRheSkgJT4lCiAgZHBseXI6OnN1bW1hcmlzZShjdXJyX3dldCA9IGxlbmd0aChhY3RpdmVbYWN0aXZlID09IFRSVUVdKSkKCmJ1cnJfY3Vycl9kcnlfZGYgPC0gZGF0YS5mcmFtZShidXJyX2N1cnJfZHJ5X21vZCRhY3QpICU+JQogIHRpYmJsZTo6cm93aWRfdG9fY29sdW1uKCJob3VyIikgJT4lCiAgZHBseXI6OnJlbmFtZShhY3RpdmUgPSBidXJyX2N1cnJfZHJ5X21vZC5hY3QpICU+JQogIGRwbHlyOjptdXRhdGUoZGF5ID0gY2VpbGluZygxOjg3NjAvMjQpKSAlPiUKICBkcGx5cjo6Z3JvdXBfYnkoZGF5KSAlPiUKICBkcGx5cjo6c3VtbWFyaXNlKGN1cnJfZHJ5ID0gbGVuZ3RoKGFjdGl2ZVthY3RpdmUgPT0gVFJVRV0pKQoKYnVycl93YXJtX3dldF9kZiA8LSBkYXRhLmZyYW1lKGJ1cnJfd2FybV93ZXRfbW9kJGFjdCkgJT4lCiAgdGliYmxlOjpyb3dpZF90b19jb2x1bW4oImhvdXIiKSAlPiUKICBkcGx5cjo6cmVuYW1lKGFjdGl2ZSA9IGJ1cnJfd2FybV93ZXRfbW9kLmFjdCkgJT4lCiAgZHBseXI6Om11dGF0ZShkYXkgPSBjZWlsaW5nKDE6ODc2MC8yNCkpICU+JQogIGRwbHlyOjpncm91cF9ieShkYXkpICU+JQogIGRwbHlyOjpzdW1tYXJpc2Uod2FybV93ZXQgPSBsZW5ndGgoYWN0aXZlW2FjdGl2ZSA9PSBUUlVFXSkpCgpidXJyX3dhcm1fZHJ5X2RmIDwtIGRhdGEuZnJhbWUoYnVycl93YXJtX2RyeV9tb2QkYWN0KSAlPiUKICB0aWJibGU6OnJvd2lkX3RvX2NvbHVtbigiaG91ciIpICU+JQogIGRwbHlyOjpyZW5hbWUoYWN0aXZlID0gYnVycl93YXJtX2RyeV9tb2QuYWN0KSAlPiUKICBkcGx5cjo6bXV0YXRlKGRheSA9IGNlaWxpbmcoMTo4NzYwLzI0KSkgJT4lCiAgZHBseXI6Omdyb3VwX2J5KGRheSkgJT4lCiAgZHBseXI6OnN1bW1hcmlzZSh3YXJtX2RyeSA9IGxlbmd0aChhY3RpdmVbYWN0aXZlID09IFRSVUVdKSkKCmJ1cnJfbW9kZWwgPC0gYnVycl9jdXJyX3dldF9kZiAlPiUKICBtZXJnZShidXJyX2N1cnJfZHJ5X2RmLCBieSA9ICJkYXkiKSAlPiUKICBtZXJnZShidXJyX3dhcm1fd2V0X2RmLCBieSA9ICJkYXkiKSAlPiUKICBtZXJnZShidXJyX3dhcm1fZHJ5X2RmLCBieSA9ICJkYXkiKSAlPiUKICBwaXZvdF9sb25nZXIoIWRheSwgbmFtZXNfdG8gPSAiY29uZGl0aW9uIiwgdmFsdWVzX3RvID0gImhvdXJzIikgJT4lCiAgZHBseXI6Om11dGF0ZShjb25kaXRpb24gPSBmYWN0b3IoY29uZGl0aW9uLCBsZXZlbHMgPSBjKCJ3YXJtX2RyeSIsICJ3YXJtX3dldCIsICJjdXJyX2RyeSIsICJjdXJyX3dldCIpKSwKICAgICAgICAgICAgICAgIHNlYXNvbiA9IGNhc2Vfd2hlbigKICAgIGRheSA+PSAzMzUgfiAic3VtbWVyIiwKICAgIGRheSA+PSAxICYgZGF5IDw9IDYxIH4gInN1bW1lciIsCiAgICBkYXkgPj0gNjIgJiBkYXkgPD0gMTUzIH4gImF1dHVtbiIsCiAgICBkYXkgPj0gMTU0ICYgZGF5IDw9IDI0NCB+ICJ3aW50ZXIiLAogICAgZGF5ID49IDI0NSAmIGRheSA8PSAzMzQgfiAic3ByaW5nIgogICAgKSkKYGBgCgojIyBNb2RlbCBvdXRwdXQgey50YWJzZXQgLnRhYnNldC1mYWRlIC50YWJzZXQtcGlsbHMgLX0KCiMjIyBUYWJsZSBTNmEgLSBTdW1tYXJ5IHsudGFic2V0IC50YWJzZXQtZmFkZSAudGFic2V0LXBpbGxzIC19IAoKKipUYWJsZSBTNmEuKiogVG90YWwgcG90ZW50aWFsIGFjdGl2aXR5IGhvdXJzIHBlciB5ZWFyICgkdF97YWN0fSQpIGZvciBhIGByIFd3X2dgIGcgZnJvZyB1bmRlciBkaWZmZXJlbnQgd2FybWluZyAoY3VycmVudCBvciB3YXJtaW5nKSBhbmQgZHJvdWdodCAobm9ybWFsIG9yIGRyb3VnaHQpIGNvbmRpdGlvbnMgd2l0aCBkaWZmZXJlbnQgd2F0ZXItc2F2aW5nIHN0cmF0ZWdpZXMuCgpgYGAge3IgdGFibGUgczZhfQpkYXRhLmZyYW1lKHN0cmF0ZWd5ID0gYygiU2hhZGUgb25seSIsICJTaGFkZSBvbmx5IiwgIlNoYWRlIG9ubHkiLCAiU2hhZGUgb25seSIsCiAgICAgICAgICAgICAgICAgICAgICAgICJXYXRlcnByb29mIiwgIldhdGVycHJvb2YiLCAiV2F0ZXJwcm9vZiIsICJXYXRlcnByb29mIiwKICAgICAgICAgICAgICAgICAgICAgICAgIkJ1cnJvd2luZyIsICJCdXJyb3dpbmciLCAiQnVycm93aW5nIiwgIkJ1cnJvd2luZyIpLAogICAgICAgICAgIHRlbXAgPSBjKCJjdXJyZW50IiwgImN1cnJlbnQiLCAid2FybWluZyIsICJ3YXJtaW5nIiksCiAgICAgICAgICAgcmFpbiA9IGMoIm5vcm1hbCIsICJkcm91Z2h0IiksCiAgICAgICAgICAgdF9hY3RfaCA9IGMoc3VtKHNoYWRfY3Vycl93ZXRfZGYkY3Vycl93ZXQpLCBzdW0oc2hhZF9jdXJyX2RyeV9kZiRjdXJyX2RyeSksIHN1bShzaGFkX3dhcm1fd2V0X2RmJHdhcm1fd2V0KSwgc3VtKHNoYWRfd2FybV9kcnlfZGYkd2FybV9kcnkpLAogICAgICAgICAgICAgICAgICAgICAgIHN1bSh0cmVlX2N1cnJfd2V0X2RmJGN1cnJfd2V0KSwgc3VtKHRyZWVfY3Vycl9kcnlfZGYkY3Vycl9kcnkpLCBzdW0odHJlZV93YXJtX3dldF9kZiR3YXJtX3dldCksIHN1bSh0cmVlX3dhcm1fZHJ5X2RmJHdhcm1fZHJ5KSwKICAgICAgICAgICAgICAgICAgICAgICBzdW0oYnVycl9jdXJyX3dldF9kZiRjdXJyX3dldCksIHN1bShidXJyX2N1cnJfZHJ5X2RmJGN1cnJfZHJ5KSwgc3VtKGJ1cnJfd2FybV93ZXRfZGYkd2FybV93ZXQpLCBzdW0oYnVycl93YXJtX2RyeV9kZiR3YXJtX2RyeSkpLAogICAgICAgICAgIHRfYWN0X3BlciA9IGMoc3VtKHNoYWRfY3Vycl93ZXRfZGYkY3Vycl93ZXQpIC8gODc2MCAqIDEwMCwgc3VtKHNoYWRfY3Vycl9kcnlfZGYkY3Vycl9kcnkpIC8gODc2MCAqIDEwMCwgc3VtKHNoYWRfd2FybV93ZXRfZGYkd2FybV93ZXQpIC8gODc2MCAqIDEwMCwgc3VtKHNoYWRfd2FybV9kcnlfZGYkd2FybV9kcnkpIC8gODc2MCAqIDEwMCwKICAgICAgICAgICAgICAgICAgICAgICBzdW0odHJlZV9jdXJyX3dldF9kZiRjdXJyX3dldCkgLyA4NzYwICogMTAwLCBzdW0odHJlZV9jdXJyX2RyeV9kZiRjdXJyX2RyeSkgLyA4NzYwICogMTAwLCBzdW0odHJlZV93YXJtX3dldF9kZiR3YXJtX3dldCkgLyA4NzYwICogMTAwLCBzdW0odHJlZV93YXJtX2RyeV9kZiR3YXJtX2RyeSkgLyA4NzYwICogMTAwLAogICAgICAgICAgICAgICAgICAgICAgIHN1bShidXJyX2N1cnJfd2V0X2RmJGN1cnJfd2V0KSAvIDg3NjAgKiAxMDAsIHN1bShidXJyX2N1cnJfZHJ5X2RmJGN1cnJfZHJ5KSAvIDg3NjAgKiAxMDAsIHN1bShidXJyX3dhcm1fd2V0X2RmJHdhcm1fd2V0KSAvIDg3NjAgKiAxMDAsIHN1bShidXJyX3dhcm1fZHJ5X2RmJHdhcm1fZHJ5KSAvIDg3NjAgKiAxMDApKSAlPiUKICBrbml0cjo6a2FibGUoY29sLm5hbWVzID0gYygiV2F0ZXItc2F2aW5nIHN0cmF0ZWd5IiwgIldhcm1pbmcgc2ltdWxhdGlvbiIsICJEcm91Z2h0IHNpbXVsYXRpb24iLCAiJHRfe2FjdH0kIChoKSIsICIkdF97YWN0fSQgKCUpIikpCmBgYAoKIyMjIFRhYmxlIFM2YiAtIFJlbGF0aXZlIGNoYW5nZSB5ZWFyIHsudGFic2V0IC50YWJzZXQtZmFkZSAudGFic2V0LXBpbGxzIC19IAoKKipUYWJsZSBTNmIuKiogQ2hhbmdlIGluICR0X3thY3R9JCAoJSkgZm9yIGVhY2ggd2F0ZXItc2F2aW5nIHN0cmF0ZWd5IHJlbGF0aXZlIHRvIHRoZSBjdXJyZW50IG5vcm1hbCBzY2VuYXJpbyB1bmRlciB3YXJtaW5nIG9ubHksIGRyb3VnaHQgb25seSwgYW5kIHdhcm1pbmcgYW5kIGRyb3VnaHQgY29tYmluZWQuIAoKYGBgIHtyIHRhYmxlIHM2Yn0KZGF0YS5mcmFtZShzdHJhdGVneSA9IGMoIlNoYWRlIG9ubHkiLCJXYXRlcnByb29mIiwgIkJ1cnJvd2luZyIpLAogICAgICAgICAgIGN1cnJfd2V0ID0gYyhzdW0oc2hhZF9jdXJyX3dldF9kZiRjdXJyX3dldCksIHN1bSh0cmVlX2N1cnJfd2V0X2RmJGN1cnJfd2V0KSwgc3VtKGJ1cnJfY3Vycl93ZXRfZGYkY3Vycl93ZXQpKSwKICAgICAgICAgICBjdXJyX2RyeSA9IGMoc3VtKHNoYWRfY3Vycl9kcnlfZGYkY3Vycl9kcnkpLCBzdW0odHJlZV9jdXJyX2RyeV9kZiRjdXJyX2RyeSksIHN1bShidXJyX2N1cnJfZHJ5X2RmJGN1cnJfZHJ5KSksCiAgICAgICAgICAgd2FybV93ZXQgPSBjKHN1bShzaGFkX3dhcm1fd2V0X2RmJHdhcm1fd2V0KSwgc3VtKHRyZWVfd2FybV93ZXRfZGYkd2FybV93ZXQpLCBzdW0oYnVycl93YXJtX3dldF9kZiR3YXJtX3dldCkpLAogICAgICAgICAgIHdhcm1fZHJ5ID0gYyhzdW0oc2hhZF93YXJtX2RyeV9kZiR3YXJtX2RyeSksIHN1bSh0cmVlX3dhcm1fZHJ5X2RmJHdhcm1fZHJ5KSwgc3VtKGJ1cnJfd2FybV9kcnlfZGYkd2FybV9kcnkpKSkgJT4lCiAgZHBseXI6Om11dGF0ZShkZWx0YV93YXJtICAgICA9ICh3YXJtX3dldCAtIGN1cnJfd2V0KSAvIGN1cnJfd2V0ICogMTAwLAogICAgICAgICAgICAgICAgZGVsdGFfZHJ5ICAgICAgPSAoY3Vycl9kcnkgLSBjdXJyX3dldCkgLyBjdXJyX3dldCAqIDEwMCwKICAgICAgICAgICAgICAgIGRlbHRhX3dhcm1fZHJ5ID0gKHdhcm1fZHJ5IC0gY3Vycl93ZXQpIC8gY3Vycl93ZXQgKiAxMDApICU+JQogIGRwbHlyOjpzZWxlY3QoLWMoY3Vycl93ZXQ6d2FybV9kcnkpKSAlPiUKICBrbml0cjo6a2FibGUoY29sLm5hbWVzID0gYygiV2F0ZXItc2F2aW5nIHN0cmF0ZWd5IiwgIiRcXERlbHRhJCB3YXJtaW5nIG9ubHkgKCUpIiwgIiRcXERlbHRhJCBkcm91Z2h0IG9ubHkgKCUpIiwgIiRcXERlbHRhJCB3YXJtaW5nIGFuZCBkcm91Z2h0ICglKSIpKQpgYGAKCiMjIyBUYWJsZSBTNmMgLSBSZWxhdGl2ZSBjaGFuZ2Ugc2Vhc29uIHsudGFic2V0IC50YWJzZXQtZmFkZSAudGFic2V0LXBpbGxzIC19IAoKKipUYWJsZSBTNmMuKiogQ2hhbmdlIGluICR0X3thY3R9JCAoJSkgZm9yIGVhY2ggd2F0ZXItc2F2aW5nIHN0cmF0ZWd5IHJlbGF0aXZlIHRvIHRoZSBjdXJyZW50IG5vcm1hbCBzY2VuYXJpbyB1bmRlciB3YXJtaW5nIG9ubHksIGRyb3VnaHQgb25seSwgYW5kIHdhcm1pbmcgYW5kIGRyb3VnaHQgY29tYmluZWQuIAoKYGBgIHtyIHRhYmxlIHM2Y30KIyBzdW1tZXIKc2hhZF9tb2RlbF9zdW1tZXIgPC0gc2hhZF9tb2RlbCAlPiUKICBkcGx5cjo6ZmlsdGVyKHNlYXNvbiA9PSAic3VtbWVyIikgJT4lCiAgZHBseXI6Omdyb3VwX2J5KGNvbmRpdGlvbikgJT4lCiAgZHBseXI6OnN1bW1hcmlzZShob3VycyA9IHN1bShob3VycykpCgp0cmVlX21vZGVsX3N1bW1lciA8LSB0cmVlX21vZGVsICU+JQogIGRwbHlyOjpmaWx0ZXIoc2Vhc29uID09ICJzdW1tZXIiKSAlPiUKICBkcGx5cjo6Z3JvdXBfYnkoY29uZGl0aW9uKSAlPiUKICBkcGx5cjo6c3VtbWFyaXNlKGhvdXJzID0gc3VtKGhvdXJzKSkKCmJ1cnJfbW9kZWxfc3VtbWVyIDwtIGJ1cnJfbW9kZWwgJT4lCiAgZHBseXI6OmZpbHRlcihzZWFzb24gPT0gInN1bW1lciIpICU+JQogIGRwbHlyOjpncm91cF9ieShjb25kaXRpb24pICU+JQogIGRwbHlyOjpzdW1tYXJpc2UoaG91cnMgPSBzdW0oaG91cnMpKQoKdGFiX3N1bW1lciA8LSBkYXRhLmZyYW1lKHN0cmF0ZWd5ID0gYygiU2hhZGUgb25seSIsIldhdGVycHJvb2YiLCAiQnVycm93aW5nIiksCiAgICAgICAgICAgY3Vycl93ZXQgPSBjKHNoYWRfbW9kZWxfc3VtbWVyJGhvdXJzWzRdLCB0cmVlX21vZGVsX3N1bW1lciRob3Vyc1s0XSwgYnVycl9tb2RlbF9zdW1tZXIkaG91cnNbNF0pLAogICAgICAgICAgIGN1cnJfZHJ5ID0gYyhzaGFkX21vZGVsX3N1bW1lciRob3Vyc1szXSwgdHJlZV9tb2RlbF9zdW1tZXIkaG91cnNbM10sIGJ1cnJfbW9kZWxfc3VtbWVyJGhvdXJzWzNdKSwKICAgICAgICAgICB3YXJtX3dldCA9IGMoc2hhZF9tb2RlbF9zdW1tZXIkaG91cnNbMl0sIHRyZWVfbW9kZWxfc3VtbWVyJGhvdXJzWzJdLCBidXJyX21vZGVsX3N1bW1lciRob3Vyc1syXSksCiAgICAgICAgICAgd2FybV9kcnkgPSBjKHNoYWRfbW9kZWxfc3VtbWVyJGhvdXJzWzFdLCB0cmVlX21vZGVsX3N1bW1lciRob3Vyc1sxXSwgYnVycl9tb2RlbF9zdW1tZXIkaG91cnNbMV0pKSAlPiUKICBkcGx5cjo6bXV0YXRlKGRlbHRhX3dhcm0gICAgID0gKHdhcm1fd2V0IC0gY3Vycl93ZXQpIC8gY3Vycl93ZXQgKiAxMDAsCiAgICAgICAgICAgICAgICBkZWx0YV9kcnkgICAgICA9IChjdXJyX2RyeSAtIGN1cnJfd2V0KSAvIGN1cnJfd2V0ICogMTAwLAogICAgICAgICAgICAgICAgZGVsdGFfd2FybV9kcnkgPSAod2FybV9kcnkgLSBjdXJyX3dldCkgLyBjdXJyX3dldCAqIDEwMCkgJT4lCiAgZHBseXI6OnNlbGVjdCgtYyhjdXJyX3dldDp3YXJtX2RyeSkpICU+JQogIHRpYmJsZTo6YWRkX3JvdyhzdHJhdGVneSA9ICIqKlN1bW1lcioqIiwgLmJlZm9yZSA9IDEpCgojIGF1dHVtbgpzaGFkX21vZGVsX2F1dHVtbiA8LSBzaGFkX21vZGVsICU+JQogIGRwbHlyOjpmaWx0ZXIoc2Vhc29uID09ICJhdXR1bW4iKSAlPiUKICBkcGx5cjo6Z3JvdXBfYnkoY29uZGl0aW9uKSAlPiUKICBkcGx5cjo6c3VtbWFyaXNlKGhvdXJzID0gc3VtKGhvdXJzKSkKCnRyZWVfbW9kZWxfYXV0dW1uIDwtIHRyZWVfbW9kZWwgJT4lCiAgZHBseXI6OmZpbHRlcihzZWFzb24gPT0gImF1dHVtbiIpICU+JQogIGRwbHlyOjpncm91cF9ieShjb25kaXRpb24pICU+JQogIGRwbHlyOjpzdW1tYXJpc2UoaG91cnMgPSBzdW0oaG91cnMpKQoKYnVycl9tb2RlbF9hdXR1bW4gPC0gYnVycl9tb2RlbCAlPiUKICBkcGx5cjo6ZmlsdGVyKHNlYXNvbiA9PSAiYXV0dW1uIikgJT4lCiAgZHBseXI6Omdyb3VwX2J5KGNvbmRpdGlvbikgJT4lCiAgZHBseXI6OnN1bW1hcmlzZShob3VycyA9IHN1bShob3VycykpCgp0YWJfYXV0dW1uIDwtIGRhdGEuZnJhbWUoc3RyYXRlZ3kgPSBjKCJTaGFkZSBvbmx5IiwiV2F0ZXJwcm9vZiIsICJCdXJyb3dpbmciKSwKICAgICAgICAgICBjdXJyX3dldCA9IGMoc2hhZF9tb2RlbF9hdXR1bW4kaG91cnNbNF0sIHRyZWVfbW9kZWxfYXV0dW1uJGhvdXJzWzRdLCBidXJyX21vZGVsX2F1dHVtbiRob3Vyc1s0XSksCiAgICAgICAgICAgY3Vycl9kcnkgPSBjKHNoYWRfbW9kZWxfYXV0dW1uJGhvdXJzWzNdLCB0cmVlX21vZGVsX2F1dHVtbiRob3Vyc1szXSwgYnVycl9tb2RlbF9hdXR1bW4kaG91cnNbM10pLAogICAgICAgICAgIHdhcm1fd2V0ID0gYyhzaGFkX21vZGVsX2F1dHVtbiRob3Vyc1syXSwgdHJlZV9tb2RlbF9hdXR1bW4kaG91cnNbMl0sIGJ1cnJfbW9kZWxfYXV0dW1uJGhvdXJzWzJdKSwKICAgICAgICAgICB3YXJtX2RyeSA9IGMoc2hhZF9tb2RlbF9hdXR1bW4kaG91cnNbMV0sIHRyZWVfbW9kZWxfYXV0dW1uJGhvdXJzWzFdLCBidXJyX21vZGVsX2F1dHVtbiRob3Vyc1sxXSkpICU+JQogIGRwbHlyOjptdXRhdGUoZGVsdGFfd2FybSAgICAgPSAod2FybV93ZXQgLSBjdXJyX3dldCkgLyBjdXJyX3dldCAqIDEwMCwKICAgICAgICAgICAgICAgIGRlbHRhX2RyeSAgICAgID0gKGN1cnJfZHJ5IC0gY3Vycl93ZXQpIC8gY3Vycl93ZXQgKiAxMDAsCiAgICAgICAgICAgICAgICBkZWx0YV93YXJtX2RyeSA9ICh3YXJtX2RyeSAtIGN1cnJfd2V0KSAvIGN1cnJfd2V0ICogMTAwKSAlPiUKICBkcGx5cjo6c2VsZWN0KC1jKGN1cnJfd2V0Ondhcm1fZHJ5KSkgJT4lCiAgdGliYmxlOjphZGRfcm93KHN0cmF0ZWd5ID0gIioqQXV0dW1uKioiLCAuYmVmb3JlID0gMSkKCiMgd2ludGVyCnNoYWRfbW9kZWxfd2ludGVyIDwtIHNoYWRfbW9kZWwgJT4lCiAgZHBseXI6OmZpbHRlcihzZWFzb24gPT0gIndpbnRlciIpICU+JQogIGRwbHlyOjpncm91cF9ieShjb25kaXRpb24pICU+JQogIGRwbHlyOjpzdW1tYXJpc2UoaG91cnMgPSBzdW0oaG91cnMpKQoKdHJlZV9tb2RlbF93aW50ZXIgPC0gdHJlZV9tb2RlbCAlPiUKICBkcGx5cjo6ZmlsdGVyKHNlYXNvbiA9PSAid2ludGVyIikgJT4lCiAgZHBseXI6Omdyb3VwX2J5KGNvbmRpdGlvbikgJT4lCiAgZHBseXI6OnN1bW1hcmlzZShob3VycyA9IHN1bShob3VycykpCgpidXJyX21vZGVsX3dpbnRlciA8LSBidXJyX21vZGVsICU+JQogIGRwbHlyOjpmaWx0ZXIoc2Vhc29uID09ICJ3aW50ZXIiKSAlPiUKICBkcGx5cjo6Z3JvdXBfYnkoY29uZGl0aW9uKSAlPiUKICBkcGx5cjo6c3VtbWFyaXNlKGhvdXJzID0gc3VtKGhvdXJzKSkKCnRhYl93aW50ZXIgPC0gZGF0YS5mcmFtZShzdHJhdGVneSA9IGMoIlNoYWRlIG9ubHkiLCJXYXRlcnByb29mIiwgIkJ1cnJvd2luZyIpLAogICAgICAgICAgIGN1cnJfd2V0ID0gYyhzaGFkX21vZGVsX3dpbnRlciRob3Vyc1s0XSwgdHJlZV9tb2RlbF93aW50ZXIkaG91cnNbNF0sIGJ1cnJfbW9kZWxfd2ludGVyJGhvdXJzWzRdKSwKICAgICAgICAgICBjdXJyX2RyeSA9IGMoc2hhZF9tb2RlbF93aW50ZXIkaG91cnNbM10sIHRyZWVfbW9kZWxfd2ludGVyJGhvdXJzWzNdLCBidXJyX21vZGVsX3dpbnRlciRob3Vyc1szXSksCiAgICAgICAgICAgd2FybV93ZXQgPSBjKHNoYWRfbW9kZWxfd2ludGVyJGhvdXJzWzJdLCB0cmVlX21vZGVsX3dpbnRlciRob3Vyc1syXSwgYnVycl9tb2RlbF93aW50ZXIkaG91cnNbMl0pLAogICAgICAgICAgIHdhcm1fZHJ5ID0gYyhzaGFkX21vZGVsX3dpbnRlciRob3Vyc1sxXSwgdHJlZV9tb2RlbF93aW50ZXIkaG91cnNbMV0sIGJ1cnJfbW9kZWxfd2ludGVyJGhvdXJzWzFdKSkgJT4lCiAgZHBseXI6Om11dGF0ZShkZWx0YV93YXJtICAgICA9ICh3YXJtX3dldCAtIGN1cnJfd2V0KSAvIGN1cnJfd2V0ICogMTAwLAogICAgICAgICAgICAgICAgZGVsdGFfZHJ5ICAgICAgPSAoY3Vycl9kcnkgLSBjdXJyX3dldCkgLyBjdXJyX3dldCAqIDEwMCwKICAgICAgICAgICAgICAgIGRlbHRhX3dhcm1fZHJ5ID0gKHdhcm1fZHJ5IC0gY3Vycl93ZXQpIC8gY3Vycl93ZXQgKiAxMDApICU+JQogIGRwbHlyOjpzZWxlY3QoLWMoY3Vycl93ZXQ6d2FybV9kcnkpKSAlPiUKICB0aWJibGU6OmFkZF9yb3coc3RyYXRlZ3kgPSAiKipXaW50ZXIqKiIsIC5iZWZvcmUgPSAxKQoKIyBzcHJpbmcKc2hhZF9tb2RlbF9zcHJpbmcgPC0gc2hhZF9tb2RlbCAlPiUKICBkcGx5cjo6ZmlsdGVyKHNlYXNvbiA9PSAic3ByaW5nIikgJT4lCiAgZHBseXI6Omdyb3VwX2J5KGNvbmRpdGlvbikgJT4lCiAgZHBseXI6OnN1bW1hcmlzZShob3VycyA9IHN1bShob3VycykpCgp0cmVlX21vZGVsX3NwcmluZyA8LSB0cmVlX21vZGVsICU+JQogIGRwbHlyOjpmaWx0ZXIoc2Vhc29uID09ICJzcHJpbmciKSAlPiUKICBkcGx5cjo6Z3JvdXBfYnkoY29uZGl0aW9uKSAlPiUKICBkcGx5cjo6c3VtbWFyaXNlKGhvdXJzID0gc3VtKGhvdXJzKSkKCmJ1cnJfbW9kZWxfc3ByaW5nIDwtIGJ1cnJfbW9kZWwgJT4lCiAgZHBseXI6OmZpbHRlcihzZWFzb24gPT0gInNwcmluZyIpICU+JQogIGRwbHlyOjpncm91cF9ieShjb25kaXRpb24pICU+JQogIGRwbHlyOjpzdW1tYXJpc2UoaG91cnMgPSBzdW0oaG91cnMpKQoKdGFiX3NwcmluZyA8LSBkYXRhLmZyYW1lKHN0cmF0ZWd5ID0gYygiU2hhZGUgb25seSIsIldhdGVycHJvb2YiLCAiQnVycm93aW5nIiksCiAgICAgICAgICAgY3Vycl93ZXQgPSBjKHNoYWRfbW9kZWxfc3ByaW5nJGhvdXJzWzRdLCB0cmVlX21vZGVsX3NwcmluZyRob3Vyc1s0XSwgYnVycl9tb2RlbF9zcHJpbmckaG91cnNbNF0pLAogICAgICAgICAgIGN1cnJfZHJ5ID0gYyhzaGFkX21vZGVsX3NwcmluZyRob3Vyc1szXSwgdHJlZV9tb2RlbF9zcHJpbmckaG91cnNbM10sIGJ1cnJfbW9kZWxfc3ByaW5nJGhvdXJzWzNdKSwKICAgICAgICAgICB3YXJtX3dldCA9IGMoc2hhZF9tb2RlbF9zcHJpbmckaG91cnNbMl0sIHRyZWVfbW9kZWxfc3ByaW5nJGhvdXJzWzJdLCBidXJyX21vZGVsX3NwcmluZyRob3Vyc1syXSksCiAgICAgICAgICAgd2FybV9kcnkgPSBjKHNoYWRfbW9kZWxfc3ByaW5nJGhvdXJzWzFdLCB0cmVlX21vZGVsX3NwcmluZyRob3Vyc1sxXSwgYnVycl9tb2RlbF9zcHJpbmckaG91cnNbMV0pKSAlPiUKICBkcGx5cjo6bXV0YXRlKGRlbHRhX3dhcm0gICAgID0gKHdhcm1fd2V0IC0gY3Vycl93ZXQpIC8gY3Vycl93ZXQgKiAxMDAsCiAgICAgICAgICAgICAgICBkZWx0YV9kcnkgICAgICA9IChjdXJyX2RyeSAtIGN1cnJfd2V0KSAvIGN1cnJfd2V0ICogMTAwLAogICAgICAgICAgICAgICAgZGVsdGFfd2FybV9kcnkgPSAod2FybV9kcnkgLSBjdXJyX3dldCkgLyBjdXJyX3dldCAqIDEwMCkgJT4lCiAgZHBseXI6OnNlbGVjdCgtYyhjdXJyX3dldDp3YXJtX2RyeSkpICU+JQogIHRpYmJsZTo6YWRkX3JvdyhzdHJhdGVneSA9ICIqKlNwcmluZyoqIiwgLmJlZm9yZSA9IDEpCgojIFJlbmRlciB0YWJsZQpiaW5kX3Jvd3ModGFiX3N1bW1lciwgdGFiX2F1dHVtbiwgdGFiX3dpbnRlciwgdGFiX3NwcmluZykgJT4lIAogIHJlbW92ZV9yb3duYW1lcygpICU+JSAKICBrbml0cjo6a2FibGUoY29sLm5hbWVzID0gYygiV2F0ZXItc2F2aW5nIHN0cmF0ZWd5IiwgIiRcXERlbHRhJCB3YXJtaW5nIG9ubHkgKCUpIiwgIiRcXERlbHRhJCBkcm91Z2h0IG9ubHkgKCUpIiwgIiRcXERlbHRhJCB3YXJtaW5nIGFuZCBkcm91Z2h0ICglKSIpKQpgYGAKCioqKgoKIyBBZGRpdGlvbmFsIGZpZ3VyZXMgey19CgpgYGB7ciBmaWcgUzExLCBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy5oZWlnaHQ9MywgZmlnLndpZHRoPTZ9CnRlbXBfZGF0IDwtIGV3bF9kYXQgJT4lIGRwbHlyOjpmaWx0ZXIoIWlzLm5hKHRydF90ZW1wKSkKCnRlbXBfZGF0ICU+JQogIGdncGxvdChhZXMoeCA9IHRydF90ZW1wLCB5ID0gc2tpbl90ZW1wKSkgKwogIGdlb21fcG9pbnQoc2l6ZSA9IDIsIGNvbG91ciA9ICJncmV5IikgKwogIGdlb21fYWJsaW5lKGludGVyY2VwdCA9IDAsIHNsb3BlID0gMSwgbGluZXR5cGUgPSAiZGFzaGVkIiwgc2l6ZSA9IDAuNSkgKwogIHN0YXRfc21vb3RoKG1ldGhvZCA9ICJsbSIsIGZvcm11bGEgPSB5IH4geCArIEkoeF40KSwgc2UgPSBGLCBjb2xvdXIgPSAiYmxhY2siKSArCiAgeWxpbSg1LDUwKSArIHhsaW0oNSw1MCkgKwogIGxhYnMoeCA9ICJBaXIgdGVtcGVyYXR1cmUgKMKwQykiLCB5ID0gIlNraW4gc3VyZmFjZSB0ZW1wZXJhdHVyZSAowrBDKSIpICsKICBteXRoZW1lKCkKYGBgCgoqKkZpZy4gUzExLioqIFJlbGF0aW9uc2hpcCBiZXR3ZWVuIGV4cG9zZWQgYWlyIHRlbXBlcmF0dXJlICjCsEMpIGR1cmluZyB0aGUgZXhwZXJpbWVudCBhbmQgdGhlIG9ic2VydmVkIHNraW4gc3VyZmFjZSB0ZW1wZXJhdHVyZSAowrBDKSBhY3Jvc3MgYHIgbGVuZ3RoKHVuaXF1ZSh0ZW1wX2RhdCRzcGVjaWVzX3BoeWxvKSlgIHNwZWNpZXMuIFRoZSBibGFjayBsaW5lIHJlcHJlc2VudHMgdGhlIG5vbi1saW5lYXIgcmVsYXRpb25zaGlwIGJldHdlZW4gYWlyIHRlbXBlcmF0dXJlIGFuZCBza2luIHRlbXBlcmF0dXJlIHdoZXJlIHRoZSBza2luIHRlbXBlcmF0dXJlIHJlbWFpbnMgYXQgfjM1wrBDIHdoZW4gZXhwb3NlZCB0byBhaXIgdGVtcGVyYXR1cmVzID4gNDDCsEMuCgoKIyBGaWd1cmVzIHstfQoKQ29kZSB0byBwcm9kdWNlIHRoZSBtYWluIGRvY3VtZW50IGZpZ3VyZXMgYXJlIGRldGFpbGVkIGJlbG93LiBGaWd1cmVzIHByb2R1Y2VkIHdlcmUgZnVydGhlciBtb2RpZmllZCBpbiBbQWRvYmUgSWxsdXN0cmF0b3JdKGh0dHBzOi8vd3d3LmFkb2JlLmNvbS9hdS9wcm9kdWN0cy9pbGx1c3RyYXRvci5odG1sKSBmb3IgcHVibGljYXRpb24uCgojIyBGaWd1cmUgMSAtIEFJIHJpc2sgey19CgpgYGB7ciBGaWcgMSwgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcuaGVpZ2h0PTcsIGZpZy53aWR0aD05LCBmaWcuc2hvdz0naGlkZSd9CiMgUmVwcm9qZWN0IG1hcHMKcm9iX3Byb2ogICA8LSAiK3Byb2o9cm9iaW4gK2xvbl8wPTAgK3hfMD0wICt5XzA9MCArZWxscHM9V0dTODQgK2RhdHVtPVdHUzg0ICt1bml0cz1tICtub19kZWZzIiAKd29ybGRfcm9iICA8LSBzcFRyYW5zZm9ybSh3b3JsZF9zcGRmLCBDUlNvYmogPSByb2JfcHJvaikKCiMgbGFuZApkYXRhKCJsYW5kIiwgcGFja2FnZSA9ICJ0bWFwIikKbGFuZF9yYXN0ZXIgPC0gYXMobGFuZCwgIlJhc3RlciIpICMgY29udmVydCBmcm9tIHN0YXIgdG8gcmFzdGVyCmxhbmRfZGYgPC0gcmFzdGVyOjphcy5kYXRhLmZyYW1lKHJhc3Rlcjo6cmFzdGVyVG9Qb2ludHMobGFuZF9yYXN0ZXIpKQoKZWxldmF0aW9uX3Jhc3RlciA8LSBwcm9qZWN0UmFzdGVyKGxhbmRfcmFzdGVyJGVsZXZhdGlvbiwgY3JzID0gcm9iX3Byb2opCnNsb3BlX3Jhc3RlciAgICAgPC0gcmFzdGVyOjp0ZXJyYWluKGVsZXZhdGlvbl9yYXN0ZXIsIG9wdCA9ICdzbG9wZScpCmFzcGVjdF9yYXN0ZXIgICAgPC0gcmFzdGVyOjp0ZXJyYWluKGVsZXZhdGlvbl9yYXN0ZXIsIG9wdCA9ICdhc3BlY3QnKQpoaWxsX3Jhc3RlciAgICAgIDwtIGhpbGxTaGFkZShzbG9wZV9yYXN0ZXIsIGFzcGVjdF9yYXN0ZXIsIDQwLCAyNzApICNzZXR0aW5nIHRoZSBlbGV2YXRpb24gYW5nbGUgKG9mIHRoZSBzdW4pIHRvIDQwIGFuZCB0aGUgZGlyZWN0aW9uIGFuZ2xlIG9mIHRoZSBsaWdodCB0byAyNzAKaGlsbF9tICAgICAgICAgICA8LSByYXN0ZXJUb1BvaW50cyhoaWxsX3Jhc3RlcikKaGlsbF9kZiAgICAgICAgICA8LSAgZGF0YS5mcmFtZShoaWxsX20pCmNvbG5hbWVzKGhpbGxfZGYpIDwtIGMoImxvbiIsICJsYXQiLCAiaGlsbCIpCgojIEZpZyAxYSAtIEFJIGN1cnJlbnQKQUlfcm9iICAgIDwtIHJhc3Rlcjo6cHJvamVjdFJhc3RlcihhaV9yYXN0LCBjcnMgPSByb2JfcHJvaikKQUlfZGZfcm9iIDwtIHJhc3Rlcjo6YXMuZGF0YS5mcmFtZShyYXN0ZXI6OnJhc3RlclRvUG9pbnRzKEFJX3JvYikpIApBSV9kZl9yb2IgPC0gQUlfZGZfcm9iICU+JSAKICAjIFJlY29kZQogIGRwbHlyOjptdXRhdGUoY2F0ZWdvcnkgPSBjYXNlX3doZW4oCiAgICBpcy5pbmZpbml0ZShsYXllcikgfiAnSHVtaWQnLAogICAgbGF5ZXIgPj0gMC42NSB+ICdIdW1pZCcsICAgICAgICAgICAgICAgICAgICAgICAKICAgIGxheWVyID49IDAuNSAmIGxheWVyIDwgMC42NSB+ICdEcnkgc3ViLWh1bWlkJywgCiAgICBsYXllciA+PSAwLjIgJiBsYXllciA8IDAuNSB+ICdTZW1pLWFyaWQnLCAgICAgIAogICAgbGF5ZXIgPj0gMC4wNSAmIGxheWVyIDwgMC4yIH4gJ0FyaWQnLCAgICAgICAgIAogICAgbGF5ZXIgPCAwLjA1IH4gJ0h5cGVyLWFyaWQnICAgICAgICAgICAgICAgICAgICAKICApKSAlPiUgCiAgIyBDb252ZXJ0IHRvIG9yZGVyZWQgZmFjdG9yCiAgZHBseXI6Om11dGF0ZShjYXRlZ29yeSA9IGZhY3RvcihjYXRlZ29yeSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldmVscyA9IGMoJ0h5cGVyLWFyaWQnLCAnQXJpZCcsICdTZW1pLWFyaWQnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnRHJ5IHN1Yi1odW1pZCcsICdIdW1pZCcpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3JkZXJlZCA9IFRSVUUpKQoKQUlfMkNfcm9iICAgIDwtIHByb2plY3RSYXN0ZXIoYWlfMkNfcmFzdCwgY3JzID0gcm9iX3Byb2opCkFJXzJDX2RmX3JvYiA8LSByYXN0ZXI6OmFzLmRhdGEuZnJhbWUocmFzdGVyOjpyYXN0ZXJUb1BvaW50cyhBSV8yQ19yb2IpKSAKQUlfMkNfZGZfcm9iIDwtIEFJXzJDX2RmX3JvYiAlPiUgCiAgIyBSZWNvZGUKICBkcGx5cjo6bXV0YXRlKGNhdGVnb3J5ID0gY2FzZV93aGVuKAogICAgaXMuaW5maW5pdGUobGF5ZXIpIH4gJ0h1bWlkJywKICAgIGxheWVyID49IDAuNjUgfiAnSHVtaWQnLCAgICAgICAgICAgICAgICAgICAgICAgCiAgICBsYXllciA+PSAwLjUgJiBsYXllciA8IDAuNjUgfiAnRHJ5IHN1Yi1odW1pZCcsIAogICAgbGF5ZXIgPj0gMC4yICYgbGF5ZXIgPCAwLjUgfiAnU2VtaS1hcmlkJywgICAgIAogICAgbGF5ZXIgPj0gMC4wNSAmIGxheWVyIDwgMC4yIH4gJ0FyaWQnLCAgICAgICAgIAogICAgbGF5ZXIgPCAwLjA1IH4gJ0h5cGVyLWFyaWQnICAgICAgICAgICAgICAgIAogICkpICU+JSAKICAjIENvbnZlcnQgdG8gb3JkZXJlZCBmYWN0b3IKICBkcGx5cjo6bXV0YXRlKGNhdGVnb3J5ID0gZmFjdG9yKGNhdGVnb3J5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV2ZWxzID0gYygnSHlwZXItYXJpZCcsICdBcmlkJywgJ1NlbWktYXJpZCcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdEcnkgc3ViLWh1bWlkJywgJ0h1bWlkJyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcmRlcmVkID0gVFJVRSkpCgpBSV80Q19yb2IgICAgPC0gcHJvamVjdFJhc3RlcihhaV80Q19yYXN0LCBjcnMgPSByb2JfcHJvaikKQUlfNENfZGZfcm9iIDwtIHJhc3Rlcjo6YXMuZGF0YS5mcmFtZShyYXN0ZXI6OnJhc3RlclRvUG9pbnRzKEFJXzRDX3JvYikpIApBSV80Q19kZl9yb2IgPC0gQUlfNENfZGZfcm9iICU+JSAKICAjIFJlY29kZQogIGRwbHlyOjptdXRhdGUoY2F0ZWdvcnkgPSBjYXNlX3doZW4oCiAgICBpcy5pbmZpbml0ZShsYXllcikgfiAnSHVtaWQnLAogICAgbGF5ZXIgPj0gMC42NSB+ICdIdW1pZCcsICAgICAgICAgICAgICAgICAgICAgICAKICAgIGxheWVyID49IDAuNSAmIGxheWVyIDwgMC42NSB+ICdEcnkgc3ViLWh1bWlkJywgCiAgICBsYXllciA+PSAwLjIgJiBsYXllciA8IDAuNSB+ICdTZW1pLWFyaWQnLCAgICAgIAogICAgbGF5ZXIgPj0gMC4wNSAmIGxheWVyIDwgMC4yIH4gJ0FyaWQnLCAgICAgICAgIAogICAgbGF5ZXIgPCAwLjA1IH4gJ0h5cGVyLWFyaWQnICAgICAgICAgICAgICAgICAgICAKICApKSAlPiUgCiAgIyBDb252ZXJ0IHRvIG9yZGVyZWQgZmFjdG9yCiAgZHBseXI6Om11dGF0ZShjYXRlZ29yeSA9IGZhY3RvcihjYXRlZ29yeSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldmVscyA9IGMoJ0h5cGVyLWFyaWQnLCAnQXJpZCcsICdTZW1pLWFyaWQnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnRHJ5IHN1Yi1odW1pZCcsICdIdW1pZCcpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3JkZXJlZCA9IFRSVUUpKQoKYXJpZF9jb2wgPC0gYygnIzhFMDYzQicsICcjQ0I2RDUzJywgJyNFOTlBMkMnLCAnI0Y1RDU3OScsICd3aGl0ZScpCmFyaWRpdHlfcGxvdCA8LSBnZ3Bsb3QoKSArCiAgZ2VvbV9yYXN0ZXIoZGF0YSA9IEFJX2RmX3JvYiwgYWVzKHkgPSB5LCB4ID0geCwgZmlsbCA9IGNhdGVnb3J5KSkgKwogIGdlb21fcG9seWdvbihkYXRhID0gd29ybGRfcm9iLCBhZXMoeCA9IGxvbmcsIHkgPSBsYXQsIGdyb3VwID0gZ3JvdXApLCBjb2xvdXIgPSAiIzY0Njg2YiIsIGZpbGwgPSBOQSwgc2l6ZSA9IDAuMSkgKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGFyaWRfY29sLAogICAgICAgICAgICAgICAgICAgIGd1aWRlID0gZ3VpZGVfbGVnZW5kKHJldmVyc2UgPSBUUlVFKSkgKwogIGdnbmV3c2NhbGU6Om5ld19zY2FsZSgiZmlsbCIpICsKICBnZW9tX3Jhc3RlcihkYXRhID0gaGlsbF9kZiAlPiUgZmlsdGVyKGhpbGwgPD0gMC42NDUpLCBhZXMobG9uLCBsYXQsIGZpbGwgPSBoaWxsLCBhbHBoYSA9IGhpbGwpLCBzaG93LmxlZ2VuZCA9IEZBTFNFKSArCiAgc2NhbGVfZmlsbF9ncmFkaWVudChsb3cgPSAiYmxhY2siLCBoaWdoID0gImdyZXkiKSArCiAgc2NhbGVfYWxwaGFfY29udGludW91cyh0cmFucyA9ICJyZXZlcnNlIikgKwogIHRoZW1lX3ZvaWQoKSArIHlsYWIoTlVMTCkgKyB4bGFiKE5VTEwpICsKICBnZ3RpdGxlKCJBcmlkaXR5IEluZGV4ICgxOTgxLTIwMTApIikgKwogIHNjYWxlX3lfY29udGludW91cyhsaW1pdHMgPSBjKC02MWU1LCA4NWU1KSwgZXhwYW5kID0gYygwLCAwKSkgKwogIHNjYWxlX3hfY29udGludW91cyhsaW1pdHMgPSBjKC0xNWU2LCAxNmU2KSwgZXhwYW5kID0gYygwLCAwKSkgKwogIHRoZW1lKGF4aXMudGl0bGUgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50ZXh0ID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIGF4aXMudGlja3MgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApKSArCiAgY29vcmRfZml4ZWQocmF0aW8gPSAxKSAgCgojIEZpZyAxYiAtIFNwZWNpZXMgcmljaG5lc3MKYW51cmFuX3JvYiAgICA8LSBwcm9qZWN0UmFzdGVyKGFudXJhbl9zciwgY3JzID0gcm9iX3Byb2opCmFudXJhbl9kZl9yb2IgPC0gcmFzdGVyOjphcy5kYXRhLmZyYW1lKHJhc3Rlcjo6cmFzdGVyVG9Qb2ludHMoYW51cmFuX3JvYikpICU+JSBkcGx5cjo6cmVuYW1lKHNwZWNpZXNfbiA9IGxheWVyKQoKc3BfYnJlYWtzID0gYygxLCA1LCAyNSwgMTAwKQphbnVyYW5fcGxvdCA8LSBnZ3Bsb3QoKSArCiAgZ2VvbV9yYXN0ZXIoZGF0YSA9IGFudXJhbl9kZl9yb2IsIGFlcyh5ID0geSwgeCA9IHgsIGZpbGwgPSBzcGVjaWVzX24pKSArCiAgZ2VvbV9wb2x5Z29uKGRhdGEgPSB3b3JsZF9yb2IsIGFlcyh4ID0gbG9uZywgeSA9IGxhdCwgZ3JvdXAgPSBncm91cCksIGNvbG91ciA9ICIjNjQ2ODZiIiwgZmlsbCA9IE5BLCBzaXplID0gMC4xKSArCiAgY29sb3JzcGFjZTo6c2NhbGVfZmlsbF9jb250aW51b3VzX3NlcXVlbnRpYWwocGFsZXR0ZSA9ICJCbHVHcm4iLCB0cmFucyA9ICJsb2ciLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrcyA9IHNwX2JyZWFrcywgbGFiZWxzID0gc3BfYnJlYWtzKSArCiAgZ2duZXdzY2FsZTo6bmV3X3NjYWxlKCJmaWxsIikgKwogIGdlb21fcmFzdGVyKGRhdGEgPSBoaWxsX2RmICU+JSBmaWx0ZXIoaGlsbCA8PSAwLjY0NSksIGFlcyhsb24sIGxhdCwgZmlsbCA9IGhpbGwsIGFscGhhID0gaGlsbCksIHNob3cubGVnZW5kID0gRkFMU0UpICsKICBzY2FsZV9maWxsX2dyYWRpZW50KGxvdyA9ICJibGFjayIsIGhpZ2ggPSAiZ3JleSIpICsKICBzY2FsZV9hbHBoYV9jb250aW51b3VzKHRyYW5zID0gInJldmVyc2UiKSArCiAgdGhlbWVfdm9pZCgpICsgeWxhYihOVUxMKSArIHhsYWIoTlVMTCkgKwogIGdndGl0bGUoIkFudXJhbiBzcGVjaWVzIHJpY2huZXNzIikgKwogIHNjYWxlX3lfY29udGludW91cyhsaW1pdHMgPSBjKC02MWU1LCA4NWU1KSwgZXhwYW5kID0gYygwLCAwKSkgKwogIHNjYWxlX3hfY29udGludW91cyhsaW1pdHMgPSBjKC0xNWU2LCAxNmU2KSwgZXhwYW5kID0gYygwLCAwKSkgKwogIHRoZW1lKGF4aXMudGl0bGUgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50ZXh0ID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIGF4aXMudGlja3MgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApKSArCiAgY29vcmRfZml4ZWQoKQoKQUlfbWVyZ2VkIDwtIG1lcmdlKEFJX2RmX3JvYiwgQUlfMkNfZGZfcm9iLCBieSA9IGMoIngiLCAieSIpLCBhbGwueCA9IFQpICU+JQogIG1lcmdlKEFJXzRDX2RmX3JvYiwgYnkgPSBjKCJ4IiwgInkiKSwgYWxsLnggPSBUKSAlPiUKICBkcGx5cjo6cmVuYW1lKGxheWVyX2N1cnJlbnQgPSBsYXllci54LAogICAgICAgICAgICAgICAgY2F0ZWdvcnlfY3VycmVudCA9IGNhdGVnb3J5LngsCiAgICAgICAgICAgICAgICBsYXllcl8yQyAgPSBsYXllci55LAogICAgICAgICAgICAgICAgY2F0ZWdvcnlfMkMgPSBjYXRlZ29yeS55LAogICAgICAgICAgICAgICAgbGF5ZXJfNEMgID0gbGF5ZXIsCiAgICAgICAgICAgICAgICBjYXRlZ29yeV80QyA9IGNhdGVnb3J5KSAlPiUKICBkcGx5cjo6bXV0YXRlKGNoYW5nZV8yQyA9IChsYXllcl8yQyAtIGxheWVyX2N1cnJlbnQgLyBsYXllcl9jdXJyZW50KSAqIDEwMCwKICAgICAgICAgICAgICAgIGNoYW5nZV8yQ19BSSA9IGNhc2Vfd2hlbigKICAgICAgICAgICAgICAgICAgY2hhbmdlXzJDID49IC0yICYgY2hhbmdlXzJDIDwyIH4gJ05vIGNoYW5nZSB0byB3ZXR0ZXInLAogICAgICAgICAgICAgICAgICBjaGFuZ2VfMkMgPj0gLTEwICYgY2hhbmdlXzJDIDwgLTIgfiAnPi0yIHRvIC0xMCUnLAogICAgICAgICAgICAgICAgICBjaGFuZ2VfMkMgPj0gLTIwICYgY2hhbmdlXzJDIDwgLTEwIH4gJz4tMTAgdG8gLTIwJScsCiAgICAgICAgICAgICAgICAgIGNoYW5nZV8yQyA+PSAtNDAgJiBjaGFuZ2VfMkMgPCAtMjAgfiAnPi0yMCB0byAtNDAlJywKICAgICAgICAgICAgICAgICAgY2hhbmdlXzJDID49IC04MCAmIGNoYW5nZV8yQyA8IC00MCB+ICc+LTQwIHRvIC04MCUnLAogICAgICAgICAgICAgICAgICBjaGFuZ2VfMkMgPCAtODAgfiAnPC04MCUnKSwKICAgICAgICAgICAgICAgICAgY2hhbmdlXzRDID0gKGxheWVyXzRDIC0gbGF5ZXJfY3VycmVudCAvIGxheWVyX2N1cnJlbnQpICogMTAwLAogICAgICAgICAgICAgICAgY2hhbmdlXzRDX0FJID0gY2FzZV93aGVuKAogICAgICAgICAgICAgICAgICBjaGFuZ2VfNEMgPj0gLTIgJiBjaGFuZ2VfNEMgPDIgfiAnTm8gY2hhbmdlIHRvIHdldHRlcicsCiAgICAgICAgICAgICAgICAgIGNoYW5nZV80QyA+PSAtMTAgJiBjaGFuZ2VfNEMgPCAtMiB+ICc+LTIgdG8gLTEwJScsCiAgICAgICAgICAgICAgICAgIGNoYW5nZV80QyA+PSAtMjAgJiBjaGFuZ2VfNEMgPCAtMTAgfiAnPi0xMCB0byAtMjAlJywKICAgICAgICAgICAgICAgICAgY2hhbmdlXzRDID49IC00MCAmIGNoYW5nZV80QyA8IC0yMCB+ICc+LTIwIHRvIC00MCUnLAogICAgICAgICAgICAgICAgICBjaGFuZ2VfNEMgPj0gLTgwICYgY2hhbmdlXzRDIDwgLTQwIH4gJz4tNDAgdG8gLTgwJScsCiAgICAgICAgICAgICAgICAgIGNoYW5nZV80QyA8IC04MCB+ICc8LTgwJScKICAgICAgICAgICAgICAgICkpICU+JSAKICBmaWx0ZXIoY2F0ZWdvcnlfY3VycmVudCAhPSAiSHlwZXItYXJpZCIpICU+JQogIGRwbHlyOjptdXRhdGUoY2hhbmdlXzJDX0FJID0gZmFjdG9yKGNoYW5nZV8yQ19BSSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSBjKCc8LTgwJScsICc+LTQwIHRvIC04MCUnLCc+LTIwIHRvIC00MCUnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJz4tMTAgdG8gLTIwJScsICc+LTIgdG8gLTEwJScsICdObyBjaGFuZ2UgdG8gd2V0dGVyJyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3JkZXJlZCA9IFRSVUUpLAogICAgICAgICAgICAgICAgY2hhbmdlXzRDX0FJID0gZmFjdG9yKGNoYW5nZV80Q19BSSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSBjKCc8LTgwJScsICc+LTQwIHRvIC04MCUnLCc+LTIwIHRvIC00MCUnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJz4tMTAgdG8gLTIwJScsICc+LTIgdG8gLTEwJScsICdObyBjaGFuZ2UgdG8gd2V0dGVyJyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3JkZXJlZCA9IFRSVUUpKQoKY2hhbmdlX2NvbCA8LSBjKCcjQjEzRjYzJywgJyNEMzVENjAnLCAnI0UzODU2NicsICcjRUVBQzdEJywgJyNGNUQxQTgnLCAnd2hpdGUnKQoKIyBGaWcgMUMgLSAyQyBEaWZmZXJlbmNlCmNoYW5nZV8yQ19wbG90IDwtIGdncGxvdCgpICsKICBnZW9tX3Jhc3RlcihkYXRhID0gQUlfbWVyZ2VkLCBhZXMoeSA9IHksIHggPSB4LCBmaWxsID0gY2hhbmdlXzJDX0FJKSkgKwogIGdlb21fcG9seWdvbihkYXRhID0gd29ybGRfcm9iLCBhZXMoeCA9IGxvbmcsIHkgPSBsYXQsIGdyb3VwID0gZ3JvdXApLCBjb2xvdXIgPSAiIzY0Njg2YiIsIGZpbGwgPSBOQSwgc2l6ZSA9IDAuMSkgKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGNoYW5nZV9jb2wsIG5hLnZhbHVlID0gIndoaXRlIikgKwogIGdnbmV3c2NhbGU6Om5ld19zY2FsZSgiZmlsbCIpICsKICBnZW9tX3Jhc3RlcihkYXRhID0gaGlsbF9kZiAlPiUgZmlsdGVyKGhpbGwgPD0gMC42NDUpLCBhZXMobG9uLCBsYXQsIGZpbGwgPSBoaWxsLCBhbHBoYSA9IGhpbGwpLCBzaG93LmxlZ2VuZCA9IEZBTFNFKSArCiAgc2NhbGVfZmlsbF9ncmFkaWVudChsb3cgPSAiYmxhY2siLCBoaWdoID0gImdyZXkiKSArCiAgc2NhbGVfYWxwaGFfY29udGludW91cyh0cmFucyA9ICJyZXZlcnNlIikgKwogIHRoZW1lX3ZvaWQoKSsgeWxhYihOVUxMKSArIHhsYWIoTlVMTCkgKwogIGdndGl0bGUoZXhwcmVzc2lvbigiQ2hhbmdlIGluIGRyeW5lc3MgKCIqRGVsdGEqIkFJICsywrBDKSIpKSArCiAgc2NhbGVfeV9jb250aW51b3VzKGxpbWl0cyA9IGMoLTYxZTUsIDg1ZTUpLCBleHBhbmQgPSBjKDAsIDApKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGxpbWl0cyA9IGMoLTE1ZTYsIDE2ZTYpLCBleHBhbmQgPSBjKDAsIDApKSArCiAgdGhlbWUoYXhpcy50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRleHQgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50aWNrcyA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCkpICsKICBjb29yZF9maXhlZChyYXRpbyA9IDEpIAoKIyBGaWcgMWQgLSA0QyBEaWZmZXJlbmNlCmNoYW5nZV80Q19wbG90IDwtIGdncGxvdCgpICsKICBnZW9tX3Jhc3RlcihkYXRhID0gQUlfbWVyZ2VkLCBhZXMoeSA9IHksIHggPSB4LCBmaWxsID0gY2hhbmdlXzRDX0FJKSkgKwogIGdlb21fcG9seWdvbihkYXRhID0gd29ybGRfcm9iLCBhZXMoeCA9IGxvbmcsIHkgPSBsYXQsIGdyb3VwID0gZ3JvdXApLCBjb2xvdXIgPSAiIzY0Njg2YiIsIGZpbGwgPSBOQSwgc2l6ZSA9IDAuMSkgKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGNoYW5nZV9jb2wsIG5hLnZhbHVlID0gIndoaXRlIikgKwogIGdnbmV3c2NhbGU6Om5ld19zY2FsZSgiZmlsbCIpICsKICBnZW9tX3Jhc3RlcihkYXRhID0gaGlsbF9kZiAlPiUgZmlsdGVyKGhpbGwgPD0gMC42NDUpLCBhZXMobG9uLCBsYXQsIGZpbGwgPSBoaWxsLCBhbHBoYSA9IGhpbGwpLCBzaG93LmxlZ2VuZCA9IEZBTFNFKSArCiAgc2NhbGVfZmlsbF9ncmFkaWVudChsb3cgPSAiYmxhY2siLCBoaWdoID0gImdyZXkiKSArCiAgc2NhbGVfYWxwaGFfY29udGludW91cyh0cmFucyA9ICJyZXZlcnNlIikgKwogIHRoZW1lX3ZvaWQoKSsgeWxhYihOVUxMKSArIHhsYWIoTlVMTCkgKwogIGdndGl0bGUoZXhwcmVzc2lvbigiQ2hhbmdlIGluIGRyeW5lc3MgKCIqRGVsdGEqIkFJICs0wrBDKSIpKSArCiAgc2NhbGVfeV9jb250aW51b3VzKGxpbWl0cyA9IGMoLTYxZTUsIDg1ZTUpLCBleHBhbmQgPSBjKDAsIDApKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGxpbWl0cyA9IGMoLTE1ZTYsIDE2ZTYpLCBleHBhbmQgPSBjKDAsIDApKSArCiAgdGhlbWUoYXhpcy50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRleHQgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50aWNrcyA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCkpICsKICBjb29yZF9maXhlZChyYXRpbyA9IDEpIAoKIyBGaWcgMWUgLSBEcnluZXNzIGFuZCBzcGVjaWVzIHJpY2huZXNzCmFyaWRfY29sXzIgPC0gYygiIzhFMDYzQiIsICIjQ0I2RDUzIiwgIiNFOTlBMkMiLCAiI0Y1RDU3OSIsICJsaWdodCBncmV5IikKc3BlY2llc19haV9wbG90IDwtIGFpX3NwX2RmICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBhcmlkaXR5LCB5ID0gc3BlY2llc19uLCBjb2xvdXIgPSBjYXRlZ29yeSkpICsKICBnZW9tX3BvaW50KHNpemUgPSAyKSArCiAgY29vcmRfdHJhbnMoeCA9ICJzcXJ0IikgKwogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gYXJpZF9jb2xfMiwKICAgICAgICAgICAgICAgICAgICBndWlkZSA9IGd1aWRlX2xlZ2VuZChyZXZlcnNlID0gVFJVRSkpICsKICBzY2FsZV94X2NvbnRpbnVvdXMobGltaXRzID0gYygwLDMpLAogICAgICAgICAgICAgICAgICAgICBicmVha3MgPSBjKDAsIDAuMDUsIDAuMiwgMC41LCAwLjY1KSkgKwogIHhsYWIoIlByZWNpcGl0YXRpb24gLyBFdmFwb3RyYW5zcGlyYXRpb24iKSArCiAgeWxhYigiU3BlY2llcyByaWNobmVzcyIpICsKICBteXRoZW1lKCkgKyB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIsIGF4aXMudGV4dC54ID0gZWxlbWVudF9ibGFuaygpLCBheGlzLnRpY2tzLnggPSBlbGVtZW50X2JsYW5rKCkpCgojIEZpZyAxZiAtIERyeW5lc3MgYW5kIHNwZWNpZXMgcmljaG5lc3MgYnkgZWNvdHlwZQplY290eXBlX2FpX3Bsb3QgPC0gYWlfc3BfZGYgJT4lCiAgZHBseXI6OmZpbHRlcihhcmlkaXR5IDw9MykgJT4lCiAgZHBseXI6OnNlbGVjdChhcmlkaXR5LCBzcGVjaWVzX246c3RyZWFtX24pICU+JQogIHRpZHlyOjpwaXZvdF9sb25nZXIoIWFyaWRpdHksIG5hbWVzX3RvID0gImVjb3R5cGUiLCB2YWx1ZXNfdG8gPSAibWVhbiIpICU+JQogIGRwbHlyOjpmaWx0ZXIoZWNvdHlwZSAhPSAic3BlY2llc19uIikgJT4lCiAgZHJvcF9uYShtZWFuKSAlPiUKICBkcGx5cjo6bXV0YXRlKGVjb3R5cGUgPSBmYWN0b3IoZWNvdHlwZSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldmVscyA9IGMoImZvc3NvcmlhbF9uIiwgImdyb3VuZF9uIiwgImFxdWF0aWNfbiIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJhcmJvcmVhbF9uIiwgInNlbWlfYXFfbiIsICJzdHJlYW1fbiIpKSkgJT4lCiAgZ2dwbG90KGFlcyh4ID0gYXJpZGl0eSwgeSA9IGVjb3R5cGUsIGdyb3VwID0gZWNvdHlwZSwgZmlsbCA9IGVjb3R5cGUpKSArCiAgZ2dyaWRnZXM6OnN0YXRfZGVuc2l0eV9yaWRnZXMoc2NhbGUgPSAxLCByZWxfbWluX2hlaWdodCA9IDAuMDEsIGFscGhhID0gMC41LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNob3cubGVnZW5kID0gRkFMU0UpICsKICBzY2FsZV9maWxsX3ZpcmlkaXNfZCgpICsKICBzY2FsZV94X2NvbnRpbnVvdXModHJhbnMgPSAic3FydCIpICsKICBsYWJzKHggPSBOVUxMLCB5ID0gTlVMTCkgKwogIG15dGhlbWUoKQoKIyBGaWcgMWcgLSBDaGFuZ2UgaW4gc3BlY2llcyBBSQojIE1lcmdlIHN1bW1hcnkgZGF0YSBieSByb3cKYXJpZF9zcF9jb21iICAgICAgICAgIDwtIGRhdGEuZnJhbWUoYmluZF9yb3dzKGFpX3NwX3N1bSwgYWlfMkNfc3Bfc3VtLCBhaV80Q19zcF9zdW0pKQphcmlkX3NwX2NvbWIkc2NlbmFyaW8gPC0gZm9yY2F0czo6ZmN0X3JlbGV2ZWwoYXJpZF9zcF9jb21iJHNjZW5hcmlvLCAiQ3VycmVudCIpCgpzcGVjaWVzX29jY19wbG90IDwtIGFyaWRfc3BfY29tYiAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gY2F0ZWdvcnksIHkgPSBsb2coYWxsX2ZyZXEpLCBncm91cCA9IHNjZW5hcmlvLCBjb2xvdXIgPSBzY2VuYXJpbywgc2hhcGUgPSBzY2VuYXJpbykpICsKICBnZW9tX3BvaW50KHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2Uod2lkdGggPSAuNSksIHNpemUgPSAxLjUpICsKICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IGMoIiNGNUQ1NzkiLCAiI0NCNkQ1MyIsICIjOEUwNjNCIikpICsKICBzY2FsZV95X2NvbnRpbnVvdXMoYnJlYWtzID0gcHJldHR5KGxvZyhhcmlkX3NwX2NvbWIkYWxsX2ZyZXEpKSwgbGFiZWxzID0gcHJldHR5KGFyaWRfc3BfY29tYiRhbGxfZnJlcSkpICsKICB5bGFiKCIlIHNwZWNpZXMiKSArIHhsYWIoTlVMTCkgKwogIG15dGhlbWUoKSArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikKCiMgRmlnIDEKcGxvdF9ncmlkKHNwZWNpZXNfYWlfcGxvdCwgZWNvdHlwZV9haV9wbG90LCBzcGVjaWVzX29jY19wbG90LCBhbGlnbiA9ICJ2IiwgbmNvbCA9IDMpICMgcGxvdCBpbiBiZXR3ZWVuLgoKY293cGxvdDo6cGxvdF9ncmlkKGFyaWRpdHlfcGxvdCArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iKSwgCiAgICAgICAgICAgICAgICAgICBhbnVyYW5fcGxvdCArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iKSwgCiAgICAgICAgICAgICAgICAgICBjaGFuZ2VfMkNfcGxvdCArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iKSwKICAgICAgICAgICAgICAgICAgIGNoYW5nZV80Q19wbG90ICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIpLAogICAgICAgICAgICAgICAgICAgYWxpZ24gPSAiaCIsIGF4aXMgPSAiYnQiLAogICAgICAgICAgICAgICAgICAgbmNvbCA9IDIpCmBgYAoKIyMgRmlndXJlIDIgLSBQRFNJIHJpc2sgey19CgpgYGB7ciBGaWcgMiwgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcuaGVpZ2h0PTYsIGZpZy53aWR0aD05LCBmaWcuc2hvdz0naGlkZSd9ClBEU0lfcmlza19yb2IgPC0gcmFzdGVyOjpwcm9qZWN0UmFzdGVyKHJhc3Rlcjo6c3RhY2soUERTSV8yQ19kaWZmX3Jhc3QsIFBEU0lfNENfZGlmZl9yYXN0LCBQRFNJX2ZyZXFfZGlmZiwgUERTSV9kdXJfZGlmZiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNhbXBsZShhbnVyYW5fc3IsIFBEU0lfNENfZGlmZl9yYXN0KSksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjcnMgPSByb2JfcHJvaikKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKUERTSV9yaXNrX2RmIDwtIHJhc3Rlcjo6YXMuZGF0YS5mcmFtZShyYXN0ZXI6OnJhc3RlclRvUG9pbnRzKFBEU0lfcmlza19yb2IpKSAlPiUKICBkcGx5cjo6cmVuYW1lKCJzcF9uIiA9IGxheWVyKSAlPiUKICBkcGx5cjo6ZmlsdGVyKCFpcy5uYShzcF9uKSkgJT4lCiAgZHBseXI6Om11dGF0ZShkZWx0YV9pbnRfMkNfYmluID0gaWZlbHNlKGRlbHRhX2ludF8yQyA8IC0xLCAxLCAwKSwgIyBkZWx0YV9QRFNJIDwgLTEKICAgICAgICAgZGVsdGFfaW50XzRDX2JpbiA9IGlmZWxzZShkZWx0YV9pbnRfNEMgPCAtMSwgMSwgMCksICMgZGVsdGFfUERTSSA8IC0xCiAgICAgICAgIGRlbHRhX2ZyZXFfMkNfYmluID0gaWZlbHNlKGRlbHRhX2ZyZXFfMkMgPjEsIDEsIDApLCAjIG1vbnRoID4gMQogICAgICAgICBkZWx0YV9mcmVxXzRDX2JpbiA9IGlmZWxzZShkZWx0YV9mcmVxXzRDID4xLCAxLCAwKSwgIyBtb250aCA+IDEKICAgICAgICAgZGVsdGFfZHVyXzJDX2JpbiA9IGlmZWxzZShkZWx0YV9kdXJfMkMgPjEsIDEsIDApLCAjIG1vbnRoID4gMQogICAgICAgICBkZWx0YV9kdXJfNENfYmluID0gaWZlbHNlKGRlbHRhX2R1cl80QyA+MSwgMSwgMCkpICU+JSAjIG1vbnRoID4gMSAKICBkcGx5cjo6cm93d2lzZSgpICU+JQogIGRwbHlyOjptdXRhdGUoY291bnRfMkMgPSBzdW0oZGVsdGFfaW50XzJDX2JpbiwgZGVsdGFfZnJlcV8yQ19iaW4sIGRlbHRhX2R1cl8yQ19iaW4sIG5hLnJtID0gVCksCiAgICAgICAgIAogICAgICAgICBjb3VudF80QyA9IHN1bShkZWx0YV9pbnRfNENfYmluLCBkZWx0YV9mcmVxXzRDX2JpbiwgZGVsdGFfZHVyXzRDX2JpbiwgbmEucm0gPSBUKSwKICAgICAgICAgcmlza18yQyAgPSBzcF9uICogY291bnRfMkMsCiAgICAgICAgIHJpc2tfNEMgID0gc3BfbiAqIGNvdW50XzRDLAogICAgICAgICBjb3VudF8yQyA9IGZhY3Rvcihjb3VudF8yQywgbGV2ZWxzID0gYygiMyIsICIyIiwgIjEiKSksCiAgICAgICAgIGNvdW50XzRDID0gZmFjdG9yKGNvdW50XzRDLCBsZXZlbHMgPSBjKCIzIiwgIjIiLCAiMSIpKQogICAgICAgICApICU+JQogIGRhdGEuZnJhbWUoKQoKIyBQbG90ClBEU0lfcmlza18yQ19wbG90IDwtIGdncGxvdCgpICsKICBnZW9tX3Jhc3RlcihkYXRhID0gUERTSV9yaXNrX2RmLCBhZXMoeSA9IHksIHggPSB4LCBmaWxsID0gY291bnRfMkMpKSArCiAgZ2VvbV9wb2x5Z29uKGRhdGEgPSB3b3JsZF9yb2IsIGFlcyh4ID0gbG9uZywgeSA9IGxhdCwgZ3JvdXAgPSBncm91cCksIGNvbG91ciA9ICIjNjQ2ODZiIiwgZmlsbCA9IE5BLCBzaXplID0gMC4xKSArCiAgc2NhbGVfZmlsbF9kaXNjcmV0ZV9zZXF1ZW50aWFsKHBhbGV0dGUgPSAiUmVkT3IiLCByZXYgPSBGKSArCiAgZ2duZXdzY2FsZTo6bmV3X3NjYWxlKCJmaWxsIikgKwogIGdlb21fcmFzdGVyKGRhdGEgPSBoaWxsX2RmICU+JSBmaWx0ZXIoaGlsbCA8PSAwLjY0NSksIGFlcyhsb24sIGxhdCwgZmlsbCA9IGhpbGwsIGFscGhhID0gaGlsbCksIHNob3cubGVnZW5kID0gRkFMU0UpICsKICBzY2FsZV9maWxsX2dyYWRpZW50KGxvdyA9ICJibGFjayIsIGhpZ2ggPSAiZ3JleSIpICsKICBzY2FsZV9hbHBoYV9jb250aW51b3VzKHRyYW5zID0gInJldmVyc2UiKSArCiAgdGhlbWVfdm9pZCgpICsgeWxhYihOVUxMKSArIHhsYWIoTlVMTCkgKwogIGdndGl0bGUoZXhwcmVzc2lvbigiKzLCsEMgYnkgMjA4MC0yMTAwIikpICsKICBzY2FsZV95X2NvbnRpbnVvdXMobGltaXRzID0gYygtNjFlNSwgODVlNSksIGV4cGFuZCA9IGMoMCwgMCkpICsKICBzY2FsZV94X2NvbnRpbnVvdXMobGltaXRzID0gYygtMTVlNiwgMTZlNiksIGV4cGFuZCA9IGMoMCwgMCkpICsKICB0aGVtZShheGlzLnRpdGxlID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIGF4aXMudGV4dCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRpY2tzID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSkgKwogIGNvb3JkX2ZpeGVkKHJhdGlvID0gMSkgIyBmaXhlZCByYXRpbwoKUERTSV9yaXNrXzRDX3Bsb3QgPC0gZ2dwbG90KCkgKwogIGdlb21fcmFzdGVyKGRhdGEgPSBQRFNJX3Jpc2tfZGYsIGFlcyh5ID0geSwgeCA9IHgsIGZpbGwgPSBjb3VudF80QykpICsKICBnZW9tX3BvbHlnb24oZGF0YSA9IHdvcmxkX3JvYiwgYWVzKHggPSBsb25nLCB5ID0gbGF0LCBncm91cCA9IGdyb3VwKSwgY29sb3VyID0gIiM2NDY4NmIiLCBmaWxsID0gTkEsIHNpemUgPSAwLjEpICsKICBzY2FsZV9maWxsX2Rpc2NyZXRlX3NlcXVlbnRpYWwocGFsZXR0ZSA9ICJSZWRPciIsIHJldiA9IEYpICsKICBnZ25ld3NjYWxlOjpuZXdfc2NhbGUoImZpbGwiKSArCiAgZ2VvbV9yYXN0ZXIoZGF0YSA9IGhpbGxfZGYgJT4lIGZpbHRlcihoaWxsIDw9IDAuNjQ1KSwgYWVzKGxvbiwgbGF0LCBmaWxsID0gaGlsbCwgYWxwaGEgPSBoaWxsKSwgc2hvdy5sZWdlbmQgPSBGQUxTRSkgKwogIHNjYWxlX2ZpbGxfZ3JhZGllbnQobG93ID0gImJsYWNrIiwgaGlnaCA9ICJncmV5IikgKwogIHNjYWxlX2FscGhhX2NvbnRpbnVvdXModHJhbnMgPSAicmV2ZXJzZSIpICsKICB0aGVtZV92b2lkKCkgKyB5bGFiKE5VTEwpICsgeGxhYihOVUxMKSArCiAgZ2d0aXRsZShleHByZXNzaW9uKCIrNMKwQyBieSAyMDgwLTIxMDAiKSkgKwogIHNjYWxlX3lfY29udGludW91cyhsaW1pdHMgPSBjKC02MWU1LCA4NWU1KSwgZXhwYW5kID0gYygwLCAwKSkgKwogIHNjYWxlX3hfY29udGludW91cyhsaW1pdHMgPSBjKC0xNWU2LCAxNmU2KSwgZXhwYW5kID0gYygwLCAwKSkgKwogIHRoZW1lKGF4aXMudGl0bGUgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50ZXh0ID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIGF4aXMudGlja3MgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApKSArCiAgY29vcmRfZml4ZWQocmF0aW8gPSAxKSAjIGZpeGVkIHJhdGlvCgpzcF8yQ19wbG90IDwtIFBEU0lfcmlza19kZiAlPiUKICBkcGx5cjo6bXV0YXRlKHJpc2tfMkNfY2F0ID0gY2FzZV93aGVuKAogICAgcmlza18yQyA9PSAwIH4gJzAnLAogICAgcmlza18yQyA+IDAgJiByaXNrXzJDIDw9MSB+ICc8MScsCiAgICByaXNrXzJDID4gMSAmIHJpc2tfMkMgPCA1IH4gJz4xIHRvIDUnLAogICAgcmlza18yQyA+PSA1ICYgcmlza18yQyA8IDEwIH4gJz41IHRvIDEwJywKICAgIHJpc2tfMkMgPj0gMTAgJiByaXNrXzJDIDwgMjAgfiAnPjEwIHRvIDIwJywKICAgIHJpc2tfMkMgPj0gMjAgJiByaXNrXzJDIDwgMTAwIH4gJz4yMCB0byAxMDAnLAogICAgcmlza18yQyA+PSAxMDAgJiByaXNrXzJDIDwgMjAwIH4gJz4xMDAgdG8gMjAwJywKICAgIHJpc2tfMkMgPiAyMDAgfiAnPjIwMCcpLAogICAgcmlza18yQyA9IG5hX2lmKHJpc2tfMkMsIDApLAogICAgcmlza18yQ19jYXQgPSBmYWN0b3Iocmlza18yQ19jYXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV2ZWxzID0gYygnPjIwMCcsJz4xMDAgdG8gMjAwJywgJz4yMCB0byAxMDAnLCc+MTAgdG8gMjAnLCAnPjUgdG8gMTAnLCAnPjEgdG8gNScsICc8MScpKSkgJT4lCiAgZ2dwbG90KCkgKwogIGdlb21fcmFzdGVyKGFlcyh5ID0geSwgeCA9IHgsIGZpbGwgPSByaXNrXzJDX2NhdCkpICsKICBnZW9tX3BvbHlnb24oZGF0YSA9IHdvcmxkX3JvYiwgYWVzKHggPSBsb25nLCB5ID0gbGF0LCBncm91cCA9IGdyb3VwKSwgY29sb3VyID0gIiM2NDY4NmIiLCBmaWxsID0gTkEsIHNpemUgPSAwLjEpICsKICBzY2FsZV9maWxsX2Rpc2NyZXRlX3NlcXVlbnRpYWwocGFsZXR0ZSA9ICJIZWF0IiwgcmV2ID0gRikgKwogIGdnbmV3c2NhbGU6Om5ld19zY2FsZSgiZmlsbCIpICsKICBnZW9tX3Jhc3RlcihkYXRhID0gaGlsbF9kZiAlPiUgZmlsdGVyKGhpbGwgPD0gMC42NDUpLCBhZXMobG9uLCBsYXQsIGZpbGwgPSBoaWxsLCBhbHBoYSA9IGhpbGwpLCBzaG93LmxlZ2VuZCA9IEZBTFNFKSArCiAgc2NhbGVfZmlsbF9ncmFkaWVudChsb3cgPSAiYmxhY2siLCBoaWdoID0gImdyZXkiKSArCiAgc2NhbGVfYWxwaGFfY29udGludW91cyh0cmFucyA9ICJyZXZlcnNlIikgKwogIHRoZW1lX3ZvaWQoKSArIHlsYWIoTlVMTCkgKyB4bGFiKE5VTEwpICsKICBzY2FsZV95X2NvbnRpbnVvdXMobGltaXRzID0gYygtNjFlNSwgODVlNSksIGV4cGFuZCA9IGMoMCwgMCkpICsKICBzY2FsZV94X2NvbnRpbnVvdXMobGltaXRzID0gYygtMTVlNiwgMTZlNiksIGV4cGFuZCA9IGMoMCwgMCkpICsKICB0aGVtZShheGlzLnRpdGxlID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIGF4aXMudGV4dCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRpY2tzID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSkgKwogIGNvb3JkX2ZpeGVkKHJhdGlvID0gMSkgIyBmaXhlZCByYXRpbwoKc3BfNENfcGxvdCA8LSBQRFNJX3Jpc2tfZGYgJT4lCiAgZHBseXI6Om11dGF0ZShyaXNrXzRDX2NhdCA9IGNhc2Vfd2hlbigKICAgIHJpc2tfNEMgPT0gMCB+ICcwJywKICAgIHJpc2tfNEMgPiAwICYgcmlza180QyA8PTEgfiAnPDEnLAogICAgcmlza180QyA+IDEgJiByaXNrXzRDIDwgNSB+ICc+MSB0byA1JywKICAgIHJpc2tfNEMgPj0gNSAmIHJpc2tfNEMgPCAxMCB+ICc+NSB0byAxMCcsCiAgICByaXNrXzRDID49IDEwICYgcmlza180QyA8IDIwIH4gJz4xMCB0byAyMCcsCiAgICByaXNrXzRDID49IDIwICYgcmlza180QyA8IDEwMCB+ICc+MjAgdG8gMTAwJywKICAgIHJpc2tfNEMgPj0gMTAwICYgcmlza180QyA8IDIwMCB+ICc+MTAwIHRvIDIwMCcsCiAgICByaXNrXzRDID4gMjAwIH4gJz4yMDAnKSwKICAgIHJpc2tfNEMgPSBuYV9pZihyaXNrXzRDLCAwKSwKICAgIHJpc2tfNENfY2F0ID0gZmFjdG9yKHJpc2tfNENfY2F0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldmVscyA9IGMoJz4yMDAnLCc+MTAwIHRvIDIwMCcsICc+MjAgdG8gMTAwJywnPjEwIHRvIDIwJywgJz41IHRvIDEwJywgJz4xIHRvIDUnLCAnPDEnKSkpICU+JQogIGdncGxvdCgpICsKICBnZW9tX3Jhc3RlcihhZXMoeSA9IHksIHggPSB4LCBmaWxsID0gcmlza180Q19jYXQpKSArCiAgZ2VvbV9wb2x5Z29uKGRhdGEgPSB3b3JsZF9yb2IsIGFlcyh4ID0gbG9uZywgeSA9IGxhdCwgZ3JvdXAgPSBncm91cCksIGNvbG91ciA9ICIjNjQ2ODZiIiwgZmlsbCA9IE5BLCBzaXplID0gMC4xKSArCiAgc2NhbGVfZmlsbF9kaXNjcmV0ZV9zZXF1ZW50aWFsKHBhbGV0dGUgPSAiSGVhdCIsIHJldiA9IEYpICsKICBnZ25ld3NjYWxlOjpuZXdfc2NhbGUoImZpbGwiKSArCiAgZ2VvbV9yYXN0ZXIoZGF0YSA9IGhpbGxfZGYgJT4lIGZpbHRlcihoaWxsIDw9IDAuNjQ1KSwgYWVzKGxvbiwgbGF0LCBmaWxsID0gaGlsbCwgYWxwaGEgPSBoaWxsKSwgc2hvdy5sZWdlbmQgPSBGQUxTRSkgKwogIHNjYWxlX2ZpbGxfZ3JhZGllbnQobG93ID0gImJsYWNrIiwgaGlnaCA9ICJncmV5IikgKwogIHNjYWxlX2FscGhhX2NvbnRpbnVvdXModHJhbnMgPSAicmV2ZXJzZSIpICsKICB0aGVtZV92b2lkKCkgKyB5bGFiKE5VTEwpICsgeGxhYihOVUxMKSArCiAgc2NhbGVfeV9jb250aW51b3VzKGxpbWl0cyA9IGMoLTYxZTUsIDg1ZTUpLCBleHBhbmQgPSBjKDAsIDApKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGxpbWl0cyA9IGMoLTE1ZTYsIDE2ZTYpLCBleHBhbmQgPSBjKDAsIDApKSArCiAgdGhlbWUoYXhpcy50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRleHQgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50aWNrcyA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCkpICsKICBjb29yZF9maXhlZChyYXRpbyA9IDEpICMgZml4ZWQgcmF0aW8KCmNvd3Bsb3Q6OnBsb3RfZ3JpZChQRFNJX3Jpc2tfMkNfcGxvdCArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiksCiAgICAgICAgICAgICAgICAgICBQRFNJX3Jpc2tfNENfcGxvdCArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiksCiAgICAgICAgICAgICAgICAgICBzcF8yQ19wbG90ICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKSwKICAgICAgICAgICAgICAgICAgIHNwXzRDX3Bsb3QgKyB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpLAogICAgICAgICAgICAgICAgICAgbmNvbCA9IDIsCiAgICAgICAgICAgICAgICAgICBhbGlnbiA9ICJoIiwgYXhpcyA9ICJidCIsIGxhYmVscyA9IGMoJ2EnLCAnYicsICdjJywgJ2QnKSkKCiNQRFNJX3Jpc2tfZGYgJT4lCiAgI2dyb3VwX2J5KGNvdW50XzJDKSAlPiUKICAjc3VtbWFyaXNlKGxlbmd0aCA9IGxlbmd0aChjb3VudF8yQykpICU+JQogICNtdXRhdGUoZnJlcSA9IGxlbmd0aCAvIGxlbmd0aChQRFNJX3Jpc2tfZGYkY291bnRfMkMpICogMTAwKQoKI1BEU0lfcmlza19kZiAlPiUKICAjZ3JvdXBfYnkoY291bnRfNEMpICU+JQogICNzdW1tYXJpc2UobGVuZ3RoID0gbGVuZ3RoKGNvdW50XzRDKSkgJT4lCiAgI211dGF0ZShmcmVxID0gbGVuZ3RoIC8gbGVuZ3RoKFBEU0lfcmlza19kZiRjb3VudF80QykgKiAxMDApCmBgYCAKCiMjIEZpZ3VyZSAzIC0gV2F0ZXIgbG9zcyB7LX0KCmBgYHtyIEZpZyAzLCBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy5oZWlnaHQ9NCwgZmlnLndpZHRoPTcsIGZpZy5zaG93PSdoaWRlJ30KIyBGaWcuIDNhIC0gRVdMCmxuVlBEX2NvbmRpdGlvbnMgPC0gbGlzdChsblZQRCA9IHNldE5hbWVzKGMoLTQuNjA1MTcsIC0yLjMwMjU4NSwgMCwgMi4zMDI1ODUpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGMocm91bmQoZXhwKC00LjYwNTE3KSwgZGlnaXRzID0gMiksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByb3VuZChleHAoLTIuMzAyNTg1KSwgZGlnaXRzID0gMSksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBleHAoMCksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByb3VuZChleHAoMi4zMDI1ODUpLCBkaWdpdHMgPSAxKSkpKQoKZXdsX2NlIDwtIGNvbmRpdGlvbmFsX2VmZmVjdHMoZXdsX21vZGVsLCBlZmZlY3RzID0gImxuTWFzczpsblZQRCIsIGludF9jb25kaXRpb25zID0gbG5WUERfY29uZGl0aW9ucykKCmV3bF9jZSA8LSBkYXRhLmZyYW1lKGV3bF9jZVtbMV1dKSAlPiUKICBkcGx5cjo6cmVuYW1lKGVzdGltYXRlID0gZXN0aW1hdGVfXywKICAgICAgICAgICAgICAgIFZQRF9jYWwgID0gZWZmZWN0Ml9fKSAlPiUKICBkcGx5cjo6bXV0YXRlKG1lYW5fbWFzc19nID0gZXhwKGxuTWFzcyksCiAgICAgICAgIFZQRF9rUGEgICAgID0gZXhwKGxuVlBEKSwKICAgICAgICAgVlBEX2NhbCAgICAgPSBhcy5udW1lcmljKGFzLmNoYXJhY3RlcihWUERfY2FsKSkpCgpld2xfbWFzc19wbG90IDwtIGV3bF9kYXQgJT4lCiAgZ2dwbG90KCkgKwogIGdlb21fcG9pbnQoYWVzKHggPSBtZWFuX21hc3NfZywgeSA9IG1nX2hfbWVhbiwgc2hhcGUgPSBzdHJhdGVneSksIHNpemUgPSAyLCBjb2xvdXIgPSAiZ3JleSIpICsKICBnZW9tX2xpbmUoZGF0YSA9IGV3bF9jZSwgYWVzKHggPSBtZWFuX21hc3NfZywgeSA9IGV4cChlc3RpbWF0ZSksIGdyb3VwID0gbG5WUEQsIGNvbG91ciA9IGxuVlBEKSwgc2l6ZSA9IDEpICsKICBnZW9tX3RleHQoZGF0YSA9IGV3bF9jZSAlPiUgZmlsdGVyKG1lYW5fbWFzc19nID09IGxhc3QobWVhbl9tYXNzX2cpKSwgCiAgICAgICAgICAgIGFlcyhsYWJlbCA9IFZQRF9jYWwsIHggPSBtZWFuX21hc3NfZyArIDUwLCB5ID0gZXhwKGVzdGltYXRlKSwgaGp1c3QgPSAtMC4wMSksCiAgICAgICAgICAgIHNpemUgPSAzKSArCiAgbGFicyh4ID0gIkJvZHkgbWFzcyAoZykiLCBjb2xvdXIgPSAiVlBEIChrUGEpIiwgc2hhcGUgPSBOVUxMKSArCiAgeWxhYihleHByZXNzaW9uKCJFV0wifigibWcifkhbMl0qT35oXnsiLTEifSkpKSArCiAgc2NhbGVfeV9jb250aW51b3VzKHRyYW5zID0gc2NhbGVzOjpsb2dfdHJhbnMoKSwgYnJlYWtzID0gYygwLjEsIDEsIDEwLCAxMDAsIDEwMDApLCBsYWJlbHMgPSBjKDAuMSwgMSwgMTAsIDEwMCwgIjEsMDAwIikpICsKICBzY2FsZV94X2NvbnRpbnVvdXModHJhbnMgPSAnbG9nMTAnKSArCiAgZXhwYW5kX2xpbWl0cyh4ID0gNTAwKSArCiAgc2NhbGVfY29sb3VyX2dyYWRpZW50Mihsb3cgPSAiIzI1NTY2OCIsIG1pZCA9ICIjMTdBNzdFIiwgaGlnaCA9ICIjODJDQzZDIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICBtaWRwb2ludCA9IC0xLAogICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWtzID0gYygtNC42MDUxNywgLTIuMzAyNTg1LCAwLCAyLjMwMjU4NSksIAogICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWxzID0gYyhyb3VuZChleHAoLTQuNjA1MTcpLCBkaWdpdHMgPSAyKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByb3VuZChleHAoLTIuMzAyNTg1KSwgZGlnaXRzID0gMSksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXhwKDApLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJvdW5kKGV4cCgyLjMwMjU4NSksIGRpZ2l0cyA9IDEpKSkgKwogIHNjYWxlX3NoYXBlX21hbnVhbCh2YWx1ZXMgPSBjKDE2LCAxLCAyLCAwKSkgKwogIG15dGhlbWUoKSArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJyaWdodCIpICsKICBndWlkZXMoY29sb3VyID0gZ3VpZGVfY29sb3VyYmFyKGJhcmhlaWdodCA9IDUsIGJhcndpZHRoID0gMC41LCBsYWJlbC5wb3NpdGlvbiA9ICJyaWdodCIpKQoKIyBGaWcuIDNiCiMgVlBEClZQRF9yYXN0IDwtIHJhc3Rlcjo6cHJvamVjdFJhc3RlcihyYXN0ZXI6OnN0YWNrKHggPSBmaWxlLnBhdGgoc3BhdGlhbF9wYXRoLCAnVGVycmFDbGltYXRlMTk4MTIwMTBfdnBkLm5jJykpLCBhbnVyYW5fc3IpICMgVlBEIHllYXIgMTk4MS0yMDEwIChrUGEpClZQRF9tZWFuX3Jhc3QgPC0gcmFzdGVyOjpjYWxjKFZQRF9yYXN0LCBmdW4gPSBtZWFuLCBuYS5ybSA9IFRSVUUpIApuYW1lcyhWUERfbWVhbl9yYXN0KSA8LSJWUEQiCgojIFdpbmQgc3BlZWQKd3NfcmFzdCA8LSByYXN0ZXI6OnByb2plY3RSYXN0ZXIocmFzdGVyOjpzdGFjayh4ID0gZmlsZS5wYXRoKHNwYXRpYWxfcGF0aCwgJ1RlcnJhQ2xpbWF0ZTE5ODEyMDEwX3dzLm5jJykpLCBhbnVyYW5fc3IpICMgV2luZCBzcGVlZCB5ZWFyIDE5ODEtMjAxMCAobS9zKQp3c19tZWFuX3Jhc3QgPC0gcmFzdGVyOjpjYWxjKHdzX3Jhc3QsIGZ1biA9IG1lYW4sIG5hLnJtID0gVFJVRSkgCm5hbWVzKHdzX21lYW5fcmFzdCkgPC0id2luZF9zcGVlZCIKCkVXTF9yaXNrX3JvYiA8LSByYXN0ZXI6OnByb2plY3RSYXN0ZXIocmFzdGVyOjpzdGFjayhWUERfbWVhbl9yYXN0LCB3c19tZWFuX3Jhc3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNhbXBsZShhbnVyYW5fc3IsIFZQRF9tZWFuX3Jhc3QpKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNycyA9IHJvYl9wcm9qKQoKIyBFc3RpbWF0ZSBFV0wgZm9yIGEgMzAgZyBncm91bmQtZHdlbGxpbmcgZnJvZwpWUERfc3BfZGYgPC0gcmFzdGVyOjphcy5kYXRhLmZyYW1lKHJhc3Rlcjo6cmFzdGVyVG9Qb2ludHMoRVdMX3Jpc2tfcm9iKSkgJT4lIAogIHJlbmFtZShzcGVjaWVzX24gPSBsYXllcikgJT4lCiAgZHJvcF9uYShzcGVjaWVzX24pICU+JQogIGRwbHlyOjptdXRhdGUod2luZF9zcGVlZF9jbV9zID0gd2luZF9zcGVlZCAqIDEwMCwgIyBmcm9tIG0vcyB0byBjbS9zCiAgICAgICAgICAgICAgICB1ID0gMC40ICogd2luZF9zcGVlZF9jbV9zIC8gbG9nKCgxMDAgLyAwLjE1KSArIDEpLCAjIHUgPSBmcmljdGlvbiB2ZWxvY2l0eQogICAgICAgICAgICAgICAgd2luZF9zcGVlZF9jb3JyID0gMi41ICogdSAqIGxvZygoMSAvIDAuMTUpICsgMSksICMgY29ycmVjdCBmb3IgcmVmZXJlbmNlIGhlaWdodCAoMTAgbSkgdG8gZ3JvdW5kIGxldmVsICgxIGNtKSBhc3N1bWluZyBsZXZlbCBncm91bmQKICAgICAgICAgICAgICAgIEVXTF9wcmVkID0gMy43NCAtIDAuMTEgKyAobG9nKFd3X2cpICogMC41NSkgKyAobG9nKFZQRCkgKiAwLjI4KSArIChsb2cod2luZF9zcGVlZF9jb3JyKSAqIDAuMzQpLAogICAgICAgICAgICAgICAgRVdMX3ByZWQgPSBleHAoRVdMX3ByZWQpICogMC4wMDEgIyBmcm9tIG1nL2ggdG8gZy9oCiAgICAgICAgICAgICAgICApCgpWUERfc3BfcGxvdCA8LSBWUERfc3BfZGYgJT4lCiAgZ2dwbG90KCkgKwogIGdlb21fcmFzdGVyKGFlcyh5ID0geSwgeCA9IHgsIGZpbGwgPSBFV0xfcHJlZCkpICsKICBnZW9tX3BvbHlnb24oZGF0YSA9IHdvcmxkX3JvYiwgYWVzKHggPSBsb25nLCB5ID0gbGF0LCBncm91cCA9IGdyb3VwKSwgY29sb3VyID0gIiM2NDY4NmIiLCBmaWxsID0gTkEsIHNpemUgPSAwLjEpICsKICBzY2FsZV9maWxsX2NvbnRpbnVvdXNfc2VxdWVudGlhbChwYWxldHRlID0gIllsR25CdSIsIHJldiA9IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWUgPSBleHByZXNzaW9uKCJFV0wifigiZyJ+SFsyXSpPfmheeyItMSJ9KSkpICsKICBnZ25ld3NjYWxlOjpuZXdfc2NhbGUoImZpbGwiKSArCiAgZ2VvbV9yYXN0ZXIoZGF0YSA9IGhpbGxfZGYgJT4lIGZpbHRlcihoaWxsIDw9IDAuNjQ1KSwgYWVzKGxvbiwgbGF0LCBmaWxsID0gaGlsbCwgYWxwaGEgPSBoaWxsKSwgc2hvdy5sZWdlbmQgPSBGQUxTRSkgKwogIHNjYWxlX2ZpbGxfZ3JhZGllbnQobG93ID0gImJsYWNrIiwgaGlnaCA9ICJncmV5IikgKwogIHNjYWxlX2FscGhhX2NvbnRpbnVvdXModHJhbnMgPSAicmV2ZXJzZSIpICsKICB0aGVtZV92b2lkKCkgKyB5bGFiKE5VTEwpICsgeGxhYihOVUxMKSArCiAgc2NhbGVfeV9jb250aW51b3VzKGxpbWl0cyA9IGMoLTYxZTUsIDg1ZTUpLCBleHBhbmQgPSBjKDAsIDApKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGxpbWl0cyA9IGMoLTE1ZTYsIDE2ZTYpLCBleHBhbmQgPSBjKDAsIDApKSArCiAgZ3VpZGVzKGZpbGwgPSBndWlkZV9jb2xvdXJiYXIoYmFyd2lkdGggPSAyMCwgYmFyaGVpZ2h0ID0gMC4yLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbC5wb3NpdGlvbiA9ICJib3R0b20iKSkgKwogIHRoZW1lX3ZvaWQoKSArIHlsYWIoTlVMTCkgKyB4bGFiKE5VTEwpICsKICB0aGVtZShheGlzLnRpdGxlID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIGF4aXMudGV4dCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRpY2tzID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSwKICAgICAgICBsZWdlbmQudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgpLCAKICAgICAgICBsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIikgKwogIGNvb3JkX2ZpeGVkKHJhdGlvID0gMSkgIyBmaXhlZCByYXRpbwoKY293cGxvdDo6cGxvdF9ncmlkKGV3bF9tYXNzX3Bsb3QsCiAgICAgICAgICAgICAgICAgICBWUERfc3BfcGxvdCwKICAgICAgICAgICAgICAgICAgIG5jb2wgPSAxLAogICAgICAgICAgICAgICAgICAgYWxpZ24gPSAiaCIsIGF4aXMgPSAiYnQiLCBsYWJlbHMgPSBjKCdhJywgJ2InKSwgcmVsX2hlaWdodHMgPSBjKDAuOCwgMSkpCmBgYAoKIyMgRmlndXJlIDQgLSBBY3Rpdml0eSByaXNrIHstfQoKYGBgIHtyIEZpZyA0LCBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy5oZWlnaHQ9NywgZmlnLndpZHRoPTgsIGZpZy5zaG93PSdoaWRlJ30Kc2hhZF9wbG90IDwtIHNoYWRfbW9kZWwgJT4lCiAgZ2dwbG90KGFlcyh4ID0gZGF5LCB5ID0gY29uZGl0aW9uLCBmaWxsID0gaG91cnMpKSArIAogIGdlb21fdGlsZSgpICsKICBzY2FsZV9maWxsX2NvbnRpbnVvdXNfZGl2ZXJnaW5nKHBhbGV0dGUgPSAiQmx1ZS1SZWQgMyIsIG1pZCA9IDEyLCByZXYgPSBUUlVFKSArCiAgeWxhYihOVUxMKSArIHhsYWIoIkRheSBvZiB0aGUgeWVhciIpICsgCiAgc2NhbGVfeF9jb250aW51b3VzKGV4cGFuZCA9IGMoMCwgMCkpICsKICBteXRoZW1lKCkgKyB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIikgKwogIGd1aWRlcyhmaWxsID0gZ3VpZGVfY29sb3VyYmFyKGJhcmhlaWdodCA9IDAuNSwgYmFyd2lkdGggPSA1LCBsYWJlbC5wb3NpdGlvbiA9ICJib3R0b20iKSkgCgp0cmVlX3Bsb3QgPC0gdHJlZV9tb2RlbCAlPiUKICBnZ3Bsb3QoYWVzKHggPSBkYXksIHkgPSBjb25kaXRpb24sIGZpbGwgPSBob3VycykpICsgCiAgZ2VvbV90aWxlKCkgKwogIHNjYWxlX2ZpbGxfY29udGludW91c19kaXZlcmdpbmcocGFsZXR0ZSA9ICJCbHVlLVJlZCAzIiwgbWlkID0gMTIsIHJldiA9IFRSVUUpICsKICB5bGFiKE5VTEwpICsgeGxhYigiRGF5IG9mIHRoZSB5ZWFyIikgKyAKICBzY2FsZV94X2NvbnRpbnVvdXMoZXhwYW5kID0gYygwLCAwKSkgKwogIG15dGhlbWUoKSArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iKSArCiAgZ3VpZGVzKGZpbGwgPSBndWlkZV9jb2xvdXJiYXIoYmFyaGVpZ2h0ID0gMC41LCBiYXJ3aWR0aCA9IDUsIGxhYmVsLnBvc2l0aW9uID0gImJvdHRvbSIpKSAKCmJ1cnJfcGxvdCA8LSBidXJyX21vZGVsICU+JQogIGdncGxvdChhZXMoeCA9IGRheSwgeSA9IGNvbmRpdGlvbiwgZmlsbCA9IGhvdXJzKSkgKyAKICBnZW9tX3RpbGUoKSArCiAgc2NhbGVfZmlsbF9jb250aW51b3VzX2RpdmVyZ2luZyhwYWxldHRlID0gIkJsdWUtUmVkIDMiLCBtaWQgPSAxMiwgcmV2ID0gVFJVRSkgKwogIHlsYWIoTlVMTCkgKyB4bGFiKCJEYXkgb2YgdGhlIHllYXIiKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGV4cGFuZCA9IGMoMCwgMCkpICsKICBteXRoZW1lKCkgKyB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIikgKwogIGd1aWRlcyhmaWxsID0gZ3VpZGVfY29sb3VyYmFyKGJhcmhlaWdodCA9IDAuNSwgYmFyd2lkdGggPSA1LCBsYWJlbC5wb3NpdGlvbiA9ICJib3R0b20iKSkgCgpwcm93XzIgPC0gY293cGxvdDo6cGxvdF9ncmlkKAogIHNoYWRfcGxvdCArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9Im5vbmUiKSwgCiAgdHJlZV9wbG90ICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0ibm9uZSIpLCAKICBidXJyX3Bsb3QgKyB0aGVtZShsZWdlbmQucG9zaXRpb24gPSJub25lIiksCiAgbmNvbCA9IDEsIGxhYmVscyA9IGMoJ2EnLCAnYicsICdjJyksCiAgYWxpZ24gPSAndicsIGF4aXMgPSAnbCcpCgpsZWdlbmRfYl8yIDwtIGNvd3Bsb3Q6OmdldF9sZWdlbmQoYnVycl9wbG90ICsgZ3VpZGVzKGNvbG9yID0gZ3VpZGVfbGVnZW5kKG5yb3cgPSAxKSkpCgpwbG90X2dyaWQocHJvd18yLCBsZWdlbmRfYl8yLCBucm93ID0gMSwgcmVsX2hlaWdodHMgPSBjKDEsIC4xKSkKYGBgCgoqKioKCiMgRXh0ZW5kZWQgZGF0YSB7LX0KCiMjIEV4dGVuZGVkIEZpZ3VyZSAxIC0gUERTSSBpbnRlbnNpdHkgcmlzayB7LX0KCmBgYHtyIEZpZyBFMSwgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcuaGVpZ2h0PTUsIGZpZy53aWR0aD05fQpQRFNJXzJDX2RpZmZfcmFzdF9jcm9wIDwtIHJhc3Rlcjo6bWFzayhjcm9wKFBEU0lfMkNfZGlmZl9yYXN0LCBleHRlbnQod29ybGQpKSwgd29ybGQpICMgY3JvcCAKUERTSV8yQ19yb2IgPC0gcmFzdGVyOjpwcm9qZWN0UmFzdGVyKHJhc3Rlcjo6c3RhY2soUERTSV8yQ19kaWZmX3Jhc3RfY3JvcCwgcmVzYW1wbGUoYW51cmFuX3NyLCBQRFNJXzJDX2RpZmZfcmFzdF9jcm9wKSksIAogICAgICAgICAgICAgICAgICAgICAgICAgIGNycyA9IHJvYl9wcm9qKQoKUERTSV80Q19kaWZmX3Jhc3RfY3JvcCA8LSByYXN0ZXI6Om1hc2soY3JvcChQRFNJXzRDX2RpZmZfcmFzdCwgZXh0ZW50KHdvcmxkKSksIHdvcmxkKSAjIGNyb3AgClBEU0lfNENfcm9iIDwtIHJhc3Rlcjo6cHJvamVjdFJhc3RlcihyYXN0ZXI6OnN0YWNrKFBEU0lfNENfZGlmZl9yYXN0X2Nyb3AsIHJlc2FtcGxlKGFudXJhbl9zciwgUERTSV80Q19kaWZmX3Jhc3RfY3JvcCkpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICBjcnMgPSByb2JfcHJvaikKClBEU0lfMkNfZGZfcm9iIDwtIHJhc3Rlcjo6YXMuZGF0YS5mcmFtZShyYXN0ZXI6OnJhc3RlclRvUG9pbnRzKFBEU0lfMkNfcm9iKSkgJT4lCiAgZHBseXI6OnJlbmFtZShsYXllciA9IGRlbHRhX2ludF8yQywKICAgICAgICAgICAgICAgIHNwZWNpZXNfbiA9IGxheWVyKSAlPiUgCiAgZHBseXI6Om11dGF0ZShjaGFuZ2UgPSBjYXNlX3doZW4oCiAgICBsYXllciA+PSA0IH4gIjQiLCAKICAgIGxheWVyID49IDMgJiBsYXllciA8IDQgfiAnMycsCiAgICBsYXllciA+PSAyICYgbGF5ZXIgPCAzIH4gJzInLCAgCiAgICBsYXllciA+PSAxICYgbGF5ZXIgPCAyIH4gJzEnLCAgCiAgICBsYXllciA+PSAtMSAmIGxheWVyIDwgMSB+ICcwJywKICAgIGxheWVyID49IC0yICYgbGF5ZXIgPCAtMSB+ICctMScsCiAgICBsYXllciA+PSAtMyAmIGxheWVyIDwgLTIgfiAnLTInLAogICAgbGF5ZXIgPj0gLTQgJiBsYXllciA8IC0zIH4gJy0zJywgICAKICAgIGxheWVyIDwgLTQgfiAnLTQnIAogICkpICU+JSAKICBkcGx5cjo6bXV0YXRlKGNoYW5nZSA9IGZhY3RvcihjaGFuZ2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV2ZWxzID0gYygnLTQnLCAnLTMnLCAnLTInLCAnLTEnLCAnMCcsICcxJywgJzInLCAnMycsICc0JyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3JkZXJlZCA9IFRSVUUpKSAlPiUKICBkcGx5cjo6ZmlsdGVyKGNoYW5nZSAhPSAiTkEiICYgc3BlY2llc19uICE9ICJOQSIpCgpQRFNJXzRDX2RmX3JvYiA8LSByYXN0ZXI6OmFzLmRhdGEuZnJhbWUocmFzdGVyOjpyYXN0ZXJUb1BvaW50cyhQRFNJXzRDX3JvYikpICU+JQogIGRwbHlyOjpyZW5hbWUobGF5ZXIgPSBkZWx0YV9pbnRfNEMsCiAgICAgICAgICAgICAgICBzcGVjaWVzX24gPSBsYXllcikgJT4lIAogIGRwbHlyOjptdXRhdGUoY2hhbmdlID0gY2FzZV93aGVuKAogICAgbGF5ZXIgPj0gNCB+ICI0IiwgCiAgICBsYXllciA+PSAzICYgbGF5ZXIgPCA0IH4gJzMnLAogICAgbGF5ZXIgPj0gMiAmIGxheWVyIDwgMyB+ICcyJywgIAogICAgbGF5ZXIgPj0gMSAmIGxheWVyIDwgMiB+ICcxJywgIAogICAgbGF5ZXIgPj0gLTEgJiBsYXllciA8IDEgfiAnMCcsCiAgICBsYXllciA+PSAtMiAmIGxheWVyIDwgLTEgfiAnLTEnLAogICAgbGF5ZXIgPj0gLTMgJiBsYXllciA8IC0yIH4gJy0yJywKICAgIGxheWVyID49IC00ICYgbGF5ZXIgPCAtMyB+ICctMycsICAgCiAgICBsYXllciA8IC00IH4gJy00JyAKICApKSAlPiUgCiAgZHBseXI6Om11dGF0ZShjaGFuZ2UgPSBmYWN0b3IoY2hhbmdlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldmVscyA9IGMoJy00JywgJy0zJywgJy0yJywgJy0xJywgJzAnLCAnMScsICcyJywgJzMnLCAnNCcpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9yZGVyZWQgPSBUUlVFKSkgJT4lCiAgZHBseXI6OmZpbHRlcihjaGFuZ2UgIT0gIk5BIiAmIHNwZWNpZXNfbiAhPSAiTkEiKQoKIyBJbnRlbnNpdHkgKzJDIC0gRXggRmlnLiAxYQpjb2xvdXJzX1BEU0kgPC0gUkNvbG9yQnJld2VyOjpicmV3ZXIucGFsKDksICJSZEJ1IikKUERTSV8yQ19wbG90IDwtIGdncGxvdCgpICsKICBnZW9tX3Jhc3RlcihkYXRhID0gUERTSV8yQ19kZl9yb2IsIGFlcyh5ID0geSwgeCA9IHgsIGZpbGwgPSBjaGFuZ2UpKSArCiAgZ2VvbV9wb2x5Z29uKGRhdGEgPSB3b3JsZF9yb2IsIGFlcyh4ID0gbG9uZywgeSA9IGxhdCwgZ3JvdXAgPSBncm91cCksIGNvbG91ciA9ICIjNjQ2ODZiIiwgZmlsbCA9IE5BLCBzaXplID0gMC4xKSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gY29sb3Vyc19QRFNJKSArCiAgZ2duZXdzY2FsZTo6bmV3X3NjYWxlKCJmaWxsIikgKwogIGdlb21fcmFzdGVyKGRhdGEgPSBoaWxsX2RmICU+JSBmaWx0ZXIoaGlsbCA8PSAwLjY0NSksIGFlcyhsb24sIGxhdCwgZmlsbCA9IGhpbGwsIGFscGhhID0gaGlsbCksIHNob3cubGVnZW5kID0gRkFMU0UpICsKICBzY2FsZV9maWxsX2dyYWRpZW50KGxvdyA9ICJibGFjayIsIGhpZ2ggPSAiZ3JleSIpICsKICBzY2FsZV9hbHBoYV9jb250aW51b3VzKHRyYW5zID0gInJldmVyc2UiKSArCiAgdGhlbWVfdm9pZCgpICsgeWxhYihOVUxMKSArIHhsYWIoTlVMTCkgKwogIGdndGl0bGUoZXhwcmVzc2lvbihEZWx0YSoiUERTSSBpbnRlbnNpdHkgKCsywrBDKSIpKSArCiAgc2NhbGVfeV9jb250aW51b3VzKGxpbWl0cyA9IGMoLTYxZTUsIDg1ZTUpLCBleHBhbmQgPSBjKDAsIDApKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGxpbWl0cyA9IGMoLTE1ZTYsIDE2ZTYpLCBleHBhbmQgPSBjKDAsIDApKSArCiAgdGhlbWUoYXhpcy50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRleHQgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50aWNrcyA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCkpICsKICBjb29yZF9maXhlZChyYXRpbyA9IDEpICMgZml4ZWQgcmF0aW8KCiMgSW50ZW5zaXR5ICs0QyAtIEV4IEZpZy4gMWMKUERTSV80Q19wbG90IDwtIGdncGxvdCgpICsKICBnZW9tX3Jhc3RlcihkYXRhID0gUERTSV80Q19kZl9yb2IsIGFlcyh5ID0geSwgeCA9IHgsIGZpbGwgPSBjaGFuZ2UpKSArCiAgZ2VvbV9wb2x5Z29uKGRhdGEgPSB3b3JsZF9yb2IsIGFlcyh4ID0gbG9uZywgeSA9IGxhdCwgZ3JvdXAgPSBncm91cCksIGNvbG91ciA9ICIjNjQ2ODZiIiwgZmlsbCA9IE5BLCBzaXplID0gMC4xKSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gY29sb3Vyc19QRFNJKSArCiAgZ2duZXdzY2FsZTo6bmV3X3NjYWxlKCJmaWxsIikgKwogIGdlb21fcmFzdGVyKGRhdGEgPSBoaWxsX2RmICU+JSBmaWx0ZXIoaGlsbCA8PSAwLjY0NSksIGFlcyhsb24sIGxhdCwgZmlsbCA9IGhpbGwsIGFscGhhID0gaGlsbCksIHNob3cubGVnZW5kID0gRkFMU0UpICsKICBzY2FsZV9maWxsX2dyYWRpZW50KGxvdyA9ICJibGFjayIsIGhpZ2ggPSAiZ3JleSIpICsKICBzY2FsZV9hbHBoYV9jb250aW51b3VzKHRyYW5zID0gInJldmVyc2UiKSArCiAgdGhlbWVfdm9pZCgpICsgeWxhYihOVUxMKSArIHhsYWIoTlVMTCkgKwogIGdndGl0bGUoZXhwcmVzc2lvbihEZWx0YSoiUERTSSBpbnRlbnNpdHkgKCs0wrBDKSIpKSArCiAgc2NhbGVfeV9jb250aW51b3VzKGxpbWl0cyA9IGMoLTYxZTUsIDg1ZTUpLCBleHBhbmQgPSBjKDAsIDApKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGxpbWl0cyA9IGMoLTE1ZTYsIDE2ZTYpLCBleHBhbmQgPSBjKDAsIDApKSArCiAgdGhlbWUoYXhpcy50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRleHQgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50aWNrcyA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCkpICsKICBjb29yZF9maXhlZChyYXRpbyA9IDEpICMgZml4ZWQgcmF0aW8KCiMgMkMgY2hhbmdlIC0gRXggRmlnIDFiClBEU0lfc3BfMkNfcGxvdCA8LSBQRFNJX3NwXzJDICU+JQogIHJvd3NfaW5zZXJ0KHRpYmJsZShjaGFuZ2VfMkMgPSAiNCIsIGFsbF9mcmVxID0gMCksIGNvbmZsaWN0ID0gImlnbm9yZSIpICU+JQogIGZpbHRlcihjaGFuZ2VfMkMgIT0gIk5BIikgJT4lCiAgZ2dwbG90KGFlcyh4ID0gY2hhbmdlXzJDLCB5ID0gYWxsX2ZyZXEsIGZpbGwgPSBjaGFuZ2VfMkMpKSArCiAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIpICsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjb2xvdXJzX1BEU0kpICsKICBnZW9tX3RleHQoYWVzKGxhYmVsID0gcm91bmQoYWxsX2ZyZXEsIDEpKSwgdmp1c3QgPSAtMSwgc2l6ZSA9IDIpICsKICB5bGFiKCIlIHNwZWNpZXMiKSArIHhsYWIoIlBEU0kiKSArCiAgeWxpbSgwLCA4MCkgKwogIGdndGl0bGUoIkdyaWQgY2VsbCBvY2N1cGllZCArMsKwQyIpICsKICBteXRoZW1lKCkgKyAKICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCkpCgojIDRDIGNoYW5nZSAtIEV4IEZpZyAxZApQRFNJX3NwXzRDX3Bsb3QgPC0gUERTSV9zcF80QyAlPiUKICBmaWx0ZXIoY2hhbmdlXzRDICE9ICJOQSIpICU+JQogIGdncGxvdChhZXMoeCA9IGNoYW5nZV80QywgeSA9IGFsbF9mcmVxLCBmaWxsID0gY2hhbmdlXzRDKSkgKwogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiKSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gY29sb3Vyc19QRFNJKSArCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHJvdW5kKGFsbF9mcmVxLCAxKSksIHZqdXN0ID0gLTEsIHNpemUgPSAyKSArCiAgeWxhYigiJSBzcGVjaWVzIikgKyB4bGFiKCJQRFNJIikgKwogIHlsaW0oMCwgODApICsKICBnZ3RpdGxlKCJHcmlkIGNlbGwgb2NjdXBpZWQgKzTCsEMiKSArCiAgbXl0aGVtZSgpICsgCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApKQoKbGVmdF9wbG90IDwtIGNvd3Bsb3Q6OnBsb3RfZ3JpZCgKICBQRFNJXzJDX3Bsb3QgKyB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpLAogIFBEU0lfNENfcGxvdCArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiksCiAgbmNvbCA9IDEsCiAgYWxpZ24gPSAiaCIsIGF4aXMgPSAiYnQiLCBsYWJlbHMgPSBjKCdhJywgJ2MnLCAnZScpKQoKcmlnaHRfcGxvdCA8LSBjb3dwbG90OjpwbG90X2dyaWQoCiAgUERTSV9zcF8yQ19wbG90ICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKSwKICBQRFNJX3NwXzRDX3Bsb3QgKyB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpLAogIG5jb2wgPSAxLAogIGFsaWduID0gImgiLCBheGlzID0gImJ0IiwgbGFiZWxzID0gYygnYicsICdkJywgJ2YnKSkKCmNvd3Bsb3Q6OnBsb3RfZ3JpZChsZWZ0X3Bsb3QsIHJpZ2h0X3Bsb3QsIG5jb2wgPSAyLCByZWxfd2lkdGhzID0gYygxLCAwLjcpKQpgYGAKCiMjIEV4dGVuZGVkIEZpZ3VyZSAyIC0gUERTSSBmcmVxdWVuY3kgcmlzayB7LX0KCmBgYHtyIEZpZyBFMiwgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcuaGVpZ2h0PTUsIGZpZy53aWR0aD05fQpmcmVxX2RpZmZfcmFzdF9jcm9wIDwtIHJhc3Rlcjo6bWFzayhjcm9wKGZyZXFfZGlmZl9yYXN0LCBleHRlbnQod29ybGQpKSwgd29ybGQpICMgY3JvcAoKUERTSV9mcmVxX3JvYiA8LSByYXN0ZXI6OnByb2plY3RSYXN0ZXIocmFzdGVyOjpzdGFjayhmcmVxX2RpZmZfcmFzdF9jcm9wLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc2FtcGxlKGFudXJhbl9zciwgZnJlcV9kaWZmX3Jhc3RfY3JvcCkpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjcnMgPSByb2JfcHJvaikKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKUERTSV9mcmVxXzJDX2RmIDwtIHJhc3Rlcjo6YXMuZGF0YS5mcmFtZShyYXN0ZXI6OnJhc3RlclRvUG9pbnRzKFBEU0lfZnJlcV9yb2IpKSAlPiUKICBkcGx5cjo6bXV0YXRlKGRpZmZfMkNfY2F0ID0gY2FzZV93aGVuKAogICAgZGlmZl8yQyA+PSAxMCB+ICIxMC0xMiIsIAogICAgZGlmZl8yQyA+PSA4ICYgZGlmZl8yQyA8IDEwIH4gJzgtMTAnLAogICAgZGlmZl8yQyA+PSA2ICYgZGlmZl8yQyA8IDggfiAnNi04JywgIAogICAgZGlmZl8yQyA+PSA0ICYgZGlmZl8yQyA8IDYgfiAnNC02JywgIAogICAgZGlmZl8yQyA+PSAyICYgZGlmZl8yQyA8IDQgfiAnMi00JywKICAgIGRpZmZfMkMgPj0gMSAmIGRpZmZfMkMgPCAyIH4gJzEtMicsCiAgICBkaWZmXzJDID4gMCAmIGRpZmZfMkMgPCAxIH4gJzAtMScsCiAgICBkaWZmXzJDID49IC0xICYgZGlmZl8yQyA8IDAgfiAnLTAtMScsCiAgICBkaWZmXzJDID49IC0yICYgZGlmZl8yQyA8IC0xIH4gJy0xLTInLAogICAgZGlmZl8yQyA+PSAtNCAmIGRpZmZfMkMgPCAtMiB+ICctMi00JwogICkpICU+JSAKICBkcGx5cjo6bXV0YXRlKGRpZmZfMkNfY2F0ID0gZmFjdG9yKGRpZmZfMkNfY2F0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV2ZWxzID0gYygnMTAtMTInLCAnOC0xMCcsICc2LTgnLCAnNC02JywgJzItNCcsICcxLTInLCAnMC0xJywnLTAtMScsICctMS0yJywgJy0yLTQnKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcmRlcmVkID0gVFJVRSkpICU+JQogIGRwbHlyOjpmaWx0ZXIoZGlmZl8yQ19jYXQgIT0gIk5BIiAmIGxheWVyICE9ICJOQSIpCgpQRFNJX2ZyZXFfNENfZGYgPC0gcmFzdGVyOjphcy5kYXRhLmZyYW1lKHJhc3Rlcjo6cmFzdGVyVG9Qb2ludHMoUERTSV9mcmVxX3JvYikpICU+JQogIGRwbHlyOjptdXRhdGUoZGlmZl80Q19jYXQgPSBjYXNlX3doZW4oCiAgICBkaWZmXzRDID49IDEwIH4gIjEwLTEyIiwgCiAgICBkaWZmXzRDID49IDggJiBkaWZmXzRDIDwgMTAgfiAnOC0xMCcsCiAgICBkaWZmXzRDID49IDYgJiBkaWZmXzRDIDwgOCB+ICc2LTgnLCAgCiAgICBkaWZmXzRDID49IDQgJiBkaWZmXzRDIDwgNiB+ICc0LTYnLCAgCiAgICBkaWZmXzRDID49IDIgJiBkaWZmXzRDIDwgNCB+ICcyLTQnLAogICAgZGlmZl80QyA+PSAxICYgZGlmZl80QyA8IDIgfiAnMS0yJywKICAgIGRpZmZfNEMgPiAwICYgZGlmZl80QyA8IDEgfiAnMC0xJywKICAgIGRpZmZfNEMgPj0gLTEgJiBkaWZmXzRDIDwgMCB+ICctMC0xJywKICAgIGRpZmZfNEMgPj0gLTIgJiBkaWZmXzRDIDwgLTEgfiAnLTEtMicsCiAgICBkaWZmXzRDID49IC00ICYgZGlmZl80QyA8IC0yIH4gJy0yLTQnCiAgKSkgJT4lIAogIGRwbHlyOjptdXRhdGUoZGlmZl80Q19jYXQgPSBmYWN0b3IoZGlmZl80Q19jYXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSBjKCcxMC0xMicsICc4LTEwJywgJzYtOCcsICc0LTYnLCAnMi00JywgJzEtMicsICcwLTEnLCAnLTAtMScsICctMS0yJywgJy0yLTQnKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9yZGVyZWQgPSBUUlVFKSkgJT4lCiAgZHBseXI6OmZpbHRlcihkaWZmXzRDX2NhdCAhPSAiTkEiICYgbGF5ZXIgIT0gIk5BIikKCiMgRnJlcSBtYXAgMkMgLSBGaWcgUzEwYQpmcmVxXzJDX3Bsb3QgPC0gZ2dwbG90KCkgKwogIGdlb21fcmFzdGVyKGRhdGEgPSBQRFNJX2ZyZXFfMkNfZGYsIGFlcyh5ID0geSwgeCA9IHgsIGZpbGwgPSBkaWZmXzJDX2NhdCkpICsKICBnZW9tX3BvbHlnb24oZGF0YSA9IHdvcmxkX3JvYiwgYWVzKHggPSBsb25nLCB5ID0gbGF0LCBncm91cCA9IGdyb3VwKSwgY29sb3VyID0gIiM2NDY4NmIiLCBmaWxsID0gTkEsIHNpemUgPSAwLjEpICsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjKCIjNjcwMDFGIiwgIiNCMjE4MkIiLCAiI0Q2NjA0RCIsICIjRjRBNTgyIiwgIiNGRERCQzciLCAiI0ZBRTlERiIsICIjRjdGN0Y3IiwgIiNkZmViZjIiKSkgKwogIGdnbmV3c2NhbGU6Om5ld19zY2FsZSgiZmlsbCIpICsKICBnZW9tX3Jhc3RlcihkYXRhID0gaGlsbF9kZiAlPiUgZmlsdGVyKGhpbGwgPD0gMC42NDUpLCBhZXMobG9uLCBsYXQsIGZpbGwgPSBoaWxsLCBhbHBoYSA9IGhpbGwpLCBzaG93LmxlZ2VuZCA9IEZBTFNFKSArCiAgc2NhbGVfZmlsbF9ncmFkaWVudChsb3cgPSAiYmxhY2siLCBoaWdoID0gImdyZXkiKSArCiAgc2NhbGVfYWxwaGFfY29udGludW91cyh0cmFucyA9ICJyZXZlcnNlIikgKwogIHRoZW1lX3ZvaWQoKSArIHlsYWIoTlVMTCkgKyB4bGFiKE5VTEwpICsKICBnZ3RpdGxlKGV4cHJlc3Npb24oIkNoYW5nZSBpbiBkcm91Z2h0IGZyZXF1ZW5jeSAoIipEZWx0YSoiUERTSSArMsKwQykiKSkgKwogIHNjYWxlX3lfY29udGludW91cyhsaW1pdHMgPSBjKC02MWU1LCA4NWU1KSwgZXhwYW5kID0gYygwLCAwKSkgKwogIHNjYWxlX3hfY29udGludW91cyhsaW1pdHMgPSBjKC0xNWU2LCAxNmU2KSwgZXhwYW5kID0gYygwLCAwKSkgKwogIHRoZW1lKGF4aXMudGl0bGUgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50ZXh0ID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIGF4aXMudGlja3MgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApKSArCiAgY29vcmRfZml4ZWQocmF0aW8gPSAxKSAjIGZpeGVkIHJhdGlvCgojIEZyZXEgbWFwIDRDIC0gRmlnIFMxMGMKZnJlcV80Q19wbG90IDwtIGdncGxvdCgpICsKICBnZW9tX3Jhc3RlcihkYXRhID0gUERTSV9mcmVxXzRDX2RmLCBhZXMoeSA9IHksIHggPSB4LCBmaWxsID0gZGlmZl80Q19jYXQpKSArCiAgZ2VvbV9wb2x5Z29uKGRhdGEgPSB3b3JsZF9yb2IsIGFlcyh4ID0gbG9uZywgeSA9IGxhdCwgZ3JvdXAgPSBncm91cCksIGNvbG91ciA9ICIjNjQ2ODZiIiwgZmlsbCA9IE5BLCBzaXplID0gMC4xKSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYygiIzY3MDAxRiIsICIjQjIxODJCIiwgIiNENjYwNEQiLCAiI0Y0QTU4MiIsICIjRkREQkM3IiwgIiNGQUU5REYiLCAiI0Y3RjdGNyIsICIjZGZlYmYyIikpICsKICBnZ25ld3NjYWxlOjpuZXdfc2NhbGUoImZpbGwiKSArCiAgZ2VvbV9yYXN0ZXIoZGF0YSA9IGhpbGxfZGYgJT4lIGZpbHRlcihoaWxsIDw9IDAuNjQ1KSwgYWVzKGxvbiwgbGF0LCBmaWxsID0gaGlsbCwgYWxwaGEgPSBoaWxsKSwgc2hvdy5sZWdlbmQgPSBGQUxTRSkgKwogIHNjYWxlX2ZpbGxfZ3JhZGllbnQobG93ID0gImJsYWNrIiwgaGlnaCA9ICJncmV5IikgKwogIHNjYWxlX2FscGhhX2NvbnRpbnVvdXModHJhbnMgPSAicmV2ZXJzZSIpICsKICB0aGVtZV92b2lkKCkgKyB5bGFiKE5VTEwpICsgeGxhYihOVUxMKSArCiAgZ2d0aXRsZShleHByZXNzaW9uKCJDaGFuZ2UgaW4gZHJvdWdodCBmcmVxdWVuY3kgKCIqRGVsdGEqIlBEU0kgKzTCsEMpIikpICsKICBzY2FsZV95X2NvbnRpbnVvdXMobGltaXRzID0gYygtNjFlNSwgODVlNSksIGV4cGFuZCA9IGMoMCwgMCkpICsKICBzY2FsZV94X2NvbnRpbnVvdXMobGltaXRzID0gYygtMTVlNiwgMTZlNiksIGV4cGFuZCA9IGMoMCwgMCkpICsKICB0aGVtZShheGlzLnRpdGxlID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIGF4aXMudGV4dCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRpY2tzID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSkgKwogIGNvb3JkX2ZpeGVkKHJhdGlvID0gMSkgIyBmaXhlZCByYXRpbwoKIyAyQyBjaGFuZ2UgLSBGaWcgUzEwYgpmcmVxX3NwXzJDIDwtIGRhdGEuZnJhbWUoUERTSV9mcmVxXzJDX2RmICU+JSAKICAgICAgICAgICAgICAgICAgICAgICAgICAgZHBseXI6Omdyb3VwX2J5KGRpZmZfMkNfY2F0KSAlPiUgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGRwbHlyOjpzdW1tYXJpc2Uoc3BlY2llc19uID0gbGVuZ3RoKGxheWVyWyFpcy5uYShsYXllcildKSkpICU+JQogIGRwbHlyOjptdXRhdGUoYWxsX2ZyZXEgID0gc3BlY2llc19uIC8gc3VtKHNwZWNpZXNfbikgKiAxMDApCgpmcmVxX3NwXzJDX3Bsb3QgPC0gZnJlcV9zcF8yQyAlPiUKICBnZ3Bsb3QoYWVzKHggPSBkaWZmXzJDX2NhdCwgeSA9IGFsbF9mcmVxLCBmaWxsID0gZGlmZl8yQ19jYXQpKSArCiAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIpICsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjKCIjNjcwMDFGIiwgIiNCMjE4MkIiLCAiI0Q2NjA0RCIsICIjRjRBNTgyIiwgIiNGRERCQzciLCAiI0ZBRTlERiIsICIjRjdGN0Y3IiwgIiNkZmViZjIiKSkgKwogIGdlb21fdGV4dChhZXMobGFiZWwgPSByb3VuZChhbGxfZnJlcSwgMSkpLCB2anVzdCA9IC0xLCBzaXplID0gMikgKwogIHlsYWIoIiUgc3BlY2llcyIpICsgeGxhYigiTW9udGhzIikgKwogIHlsaW0oMCwgNjApICsKICBnZ3RpdGxlKCJHcmlkIGNlbGwgb2NjdXBpZWQgKzLCsEMiKSArCiAgbXl0aGVtZSgpICsgCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApKQoKIyA0QyBjaGFuZ2UgLSBGaWcgUzEwZApmcmVxX3NwXzRDIDwtIGRhdGEuZnJhbWUoUERTSV9mcmVxXzRDX2RmICU+JSBkcGx5cjo6Z3JvdXBfYnkoZGlmZl80Q19jYXQpICU+JQogICAgICAgICAgICAgICAgICAgICAgICAgICBkcGx5cjo6c3VtbWFyaXNlKHNwZWNpZXNfbiA9IGxlbmd0aChsYXllclshaXMubmEobGF5ZXIpXSkpKSAlPiUKICBkcGx5cjo6bXV0YXRlKGFsbF9mcmVxICA9IHNwZWNpZXNfbiAvIHN1bShzcGVjaWVzX24pICogMTAwKQoKZnJlcV9zcF80Q19wbG90IDwtIGZyZXFfc3BfNEMgJT4lCiAgZ2dwbG90KGFlcyh4ID0gZGlmZl80Q19jYXQsIHkgPSBhbGxfZnJlcSwgZmlsbCA9IGRpZmZfNENfY2F0KSkgKwogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiKSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYygiIzY3MDAxRiIsICIjQjIxODJCIiwgIiNENjYwNEQiLCAiI0Y0QTU4MiIsICIjRkREQkM3IiwgIiNGQUU5REYiLCAiI0Y3RjdGNyIsICIjZGZlYmYyIikpICsKICBnZW9tX3RleHQoYWVzKGxhYmVsID0gcm91bmQoYWxsX2ZyZXEsIDEpKSwgdmp1c3QgPSAtMSwgc2l6ZSA9IDIpICsKICB5bGFiKCIlIHNwZWNpZXMiKSArIHhsYWIoIk1vbnRocyIpICsKICB5bGltKDAsIDYwKSArCiAgZ2d0aXRsZSgiR3JpZCBjZWxsIG9jY3VwaWVkICs0wrBDIikgKwogIG15dGhlbWUoKSArIAogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSkKCmxlZnRfcGxvdDIgPC0gY293cGxvdDo6cGxvdF9ncmlkKAogIGZyZXFfMkNfcGxvdCArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiksCiAgZnJlcV80Q19wbG90ICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKSwKICBuY29sID0gMSwKICBhbGlnbiA9ICJoIiwgYXhpcyA9ICJidCIsIGxhYmVscyA9IGMoJ2EnLCAnYycpKQoKcmlnaHRfcGxvdDIgPC0gY293cGxvdDo6cGxvdF9ncmlkKAogIGZyZXFfc3BfMkNfcGxvdCArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiksCiAgZnJlcV9zcF80Q19wbG90ICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKSwKICBuY29sID0gMSwKICBhbGlnbiA9ICJoIiwgYXhpcyA9ICJidCIsIGxhYmVscyA9IGMoJ2InLCAnZCcpKQoKY293cGxvdDo6cGxvdF9ncmlkKGxlZnRfcGxvdDIsIHJpZ2h0X3Bsb3QyLCBuY29sID0gMiwgcmVsX3dpZHRocyA9IGMoMSwgMC43KSkKYGBgCgojIyBFeHRlbmRlZCBGaWd1cmUgMyAtIFBEU0kgZHVyYXRpb24gcmlzayB7LX0KCmBgYHtyIEZpZyBFMywgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcuaGVpZ2h0PTUsIGZpZy53aWR0aD05fQpQRFNJX2R1cl9kaWZmX2Nyb3AgPC0gcmFzdGVyOjptYXNrKGNyb3AoUERTSV9kdXJfZGlmZiwgZXh0ZW50KHdvcmxkKSksIHdvcmxkKSAjIGNyb3AKClBEU0lfZHVyX3JvYiA8LSByYXN0ZXI6OnByb2plY3RSYXN0ZXIocmFzdGVyOjpzdGFjayhQRFNJX2R1cl9kaWZmX2Nyb3AsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzYW1wbGUoYW51cmFuX3NyLCBQRFNJX2R1cl9kaWZmX2Nyb3ApKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3JzID0gcm9iX3Byb2opCgpQRFNJX2R1cl8yQ19kZiA8LSByYXN0ZXI6OmFzLmRhdGEuZnJhbWUocmFzdGVyOjpyYXN0ZXJUb1BvaW50cyhQRFNJX2R1cl9yb2IpKSAlPiUKICBkcGx5cjo6cmVuYW1lKCJzcF9uIiA9IGxheWVyKSAlPiUKICBkcGx5cjo6ZmlsdGVyKCFpcy5uYShzcF9uKSkgJT4lCiAgZHBseXI6Om11dGF0ZShkaWZmXzJDX2NhdCA9IGNhc2Vfd2hlbigKICAgIGRlbHRhX2R1cl8yQyA+PSAxMCB+ICI+MTAiLCAKICAgIGRlbHRhX2R1cl8yQyA+PSA4ICYgZGVsdGFfZHVyXzJDIDwgMTAgfiAnOC0xMCcsCiAgICBkZWx0YV9kdXJfMkMgPj0gNiAmIGRlbHRhX2R1cl8yQyA8IDggfiAnNi04JywgIAogICAgZGVsdGFfZHVyXzJDID49IDQgJiBkZWx0YV9kdXJfMkMgPCA2IH4gJzQtNicsICAKICAgIGRlbHRhX2R1cl8yQyA+PSAyICYgZGVsdGFfZHVyXzJDIDwgNCB+ICcyLTQnLAogICAgZGVsdGFfZHVyXzJDID49IDEgJiBkZWx0YV9kdXJfMkMgPCAyIH4gJzEtMicsCiAgICBkZWx0YV9kdXJfMkMgPiAwICYgZGVsdGFfZHVyXzJDIDwgMSB+ICcwLTEnLAogICAgZGVsdGFfZHVyXzJDID49IC0xICYgZGVsdGFfZHVyXzJDIDwgMCB+ICctMC0xJywKICAgIGRlbHRhX2R1cl8yQyA+PSAtMiAmIGRlbHRhX2R1cl8yQyA8IC0xIH4gJy0xLTInLAogICAgZGVsdGFfZHVyXzJDID49IC00ICYgZGVsdGFfZHVyXzJDIDwgLTIgfiAnLTItNCcsCiAgICBkZWx0YV9kdXJfMkMgPj0gLTggJiBkZWx0YV9kdXJfMkMgPCAtNiB+ICctNi04JywKICAgIGRlbHRhX2R1cl8yQyA+PSAtMTAgJiBkZWx0YV9kdXJfMkMgPCAtOCB+ICctOC0xMCcsICAgCiAgICBkZWx0YV9kdXJfMkMgPCAtMTAgfiAnPC0xMCcgCiAgKSkgJT4lIAogIGRwbHlyOjptdXRhdGUoZGlmZl8yQ19jYXQgPSBmYWN0b3IoZGlmZl8yQ19jYXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV2ZWxzID0gYygnPjEwJywgJzgtMTAnLCAnNi04JywgJzQtNicsICcyLTQnLCAnMS0yJywgIjAtMSIsICctMC0xJywgJy0xLTInLCAnLTItNCcsICctNC02JywgJy02LTgnLCAnLTgtMTAnLCAnPC0xMCcpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9yZGVyZWQgPSBUUlVFKSkgJT4lCiAgZHBseXI6OmZpbHRlcihkaWZmXzJDX2NhdCAhPSAiTkEiKQoKUERTSV9kdXJfNENfZGYgPC0gcmFzdGVyOjphcy5kYXRhLmZyYW1lKHJhc3Rlcjo6cmFzdGVyVG9Qb2ludHMoUERTSV9kdXJfcm9iKSkgJT4lCiAgZHBseXI6OnJlbmFtZSgic3BfbiIgPSBsYXllcikgJT4lCiAgZHBseXI6OmZpbHRlcighaXMubmEoc3BfbikpICU+JQogIGRwbHlyOjptdXRhdGUoZGlmZl80Q19jYXQgPSBjYXNlX3doZW4oCiAgICBkZWx0YV9kdXJfNEMgPj0gMTAgfiAiPjEwIiwgCiAgICBkZWx0YV9kdXJfNEMgPj0gOCAmIGRlbHRhX2R1cl80QyA8IDEwIH4gJzgtMTAnLAogICAgZGVsdGFfZHVyXzRDID49IDYgJiBkZWx0YV9kdXJfNEMgPCA4IH4gJzYtOCcsICAKICAgIGRlbHRhX2R1cl80QyA+PSA0ICYgZGVsdGFfZHVyXzRDIDwgNiB+ICc0LTYnLCAgCiAgICBkZWx0YV9kdXJfNEMgPj0gMiAmIGRlbHRhX2R1cl80QyA8IDQgfiAnMi00JywKICAgIGRlbHRhX2R1cl80QyA+PSAxICYgZGVsdGFfZHVyXzRDIDwgMiB+ICcxLTInLAogICAgZGVsdGFfZHVyXzRDID4gMCAmIGRlbHRhX2R1cl80QyA8IDEgfiAnMC0xJywKICAgIGRlbHRhX2R1cl80QyA+PSAtMSAmIGRlbHRhX2R1cl80QyA8IDAgfiAnLTAtMScsCiAgICBkZWx0YV9kdXJfNEMgPj0gLTIgJiBkZWx0YV9kdXJfNEMgPCAtMSB+ICctMS0yJywKICAgIGRlbHRhX2R1cl80QyA+PSAtNCAmIGRlbHRhX2R1cl80QyA8IC0yIH4gJy0yLTQnLAogICAgZGVsdGFfZHVyXzRDID49IC02ICYgZGVsdGFfZHVyXzRDIDwgLTQgfiAnLTQtNicsCiAgICBkZWx0YV9kdXJfNEMgPj0gLTggJiBkZWx0YV9kdXJfNEMgPCAtNiB+ICctNi04JywKICAgIGRlbHRhX2R1cl80QyA+PSAtMTAgJiBkZWx0YV9kdXJfNEMgPCAtOCB+ICctOC0xMCcsICAgCiAgICBkZWx0YV9kdXJfNEMgPCAtMTAgfiAnPC0xMCcgCiAgKSkgJT4lIAogIGRwbHlyOjptdXRhdGUoZGlmZl80Q19jYXQgPSBmYWN0b3IoZGlmZl80Q19jYXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV2ZWxzID0gYygnPjEwJywgJzgtMTAnLCAnNi04JywgJzQtNicsICcyLTQnLCAnMS0yJywgIjAtMSIsICctMC0xJywgJy0xLTInLCAnLTItNCcsICctNC02JywgJy02LTgnLCAnLTgtMTAnLCAnPC0xMCcpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9yZGVyZWQgPSBUUlVFKSkgJT4lCiAgZHBseXI6OmZpbHRlcihkaWZmXzRDX2NhdCAhPSAiTkEiKQoKZHVyXzJDX3Bsb3QgPC0gZ2dwbG90KCkgKwogIGdlb21fcmFzdGVyKGRhdGEgPSBQRFNJX2R1cl8yQ19kZiwgYWVzKHkgPSB5LCB4ID0geCwgZmlsbCA9IGRpZmZfMkNfY2F0KSkgKwogIGdlb21fcG9seWdvbihkYXRhID0gd29ybGRfcm9iLCBhZXMoeCA9IGxvbmcsIHkgPSBsYXQsIGdyb3VwID0gZ3JvdXApLCBjb2xvdXIgPSAiIzY0Njg2YiIsIGZpbGwgPSBOQSwgc2l6ZSA9IDAuMSkgKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGMoIiM2NzAwMUYiLCAiI0IyMTgyQiIsICIjRDY2MDREIiwgIiNGNEE1ODIiLCAiI0ZEREJDNyIsICIjRkFFOURGIiwgIiNGN0Y3RjciLCAiI2RmZWJmMiIsICIjRDFFNUYwIikpICsKICBnZ25ld3NjYWxlOjpuZXdfc2NhbGUoImZpbGwiKSArCiAgZ2VvbV9yYXN0ZXIoZGF0YSA9IGhpbGxfZGYgJT4lIGZpbHRlcihoaWxsIDw9IDAuNjQ1KSwgYWVzKGxvbiwgbGF0LCBmaWxsID0gaGlsbCwgYWxwaGEgPSBoaWxsKSwgc2hvdy5sZWdlbmQgPSBGQUxTRSkgKwogIHNjYWxlX2ZpbGxfZ3JhZGllbnQobG93ID0gImJsYWNrIiwgaGlnaCA9ICJncmV5IikgKwogIHNjYWxlX2FscGhhX2NvbnRpbnVvdXModHJhbnMgPSAicmV2ZXJzZSIpICsKICB0aGVtZV92b2lkKCkgKyB5bGFiKE5VTEwpICsgeGxhYihOVUxMKSArCiAgZ2d0aXRsZShleHByZXNzaW9uKCJDaGFuZ2UgaW4gZHJvdWdodCBkdXJhdGlvbiAoIipEZWx0YSoiUERTSSArMsKwQykiKSkgKwogIHNjYWxlX3lfY29udGludW91cyhsaW1pdHMgPSBjKC02MWU1LCA4NWU1KSwgZXhwYW5kID0gYygwLCAwKSkgKwogIHNjYWxlX3hfY29udGludW91cyhsaW1pdHMgPSBjKC0xNWU2LCAxNmU2KSwgZXhwYW5kID0gYygwLCAwKSkgKwogIHRoZW1lKGF4aXMudGl0bGUgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50ZXh0ID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIGF4aXMudGlja3MgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApKSArCiAgY29vcmRfZml4ZWQocmF0aW8gPSAxKSAjIGZpeGVkIHJhdGlvCgpkdXJfNENfcGxvdCA8LSBnZ3Bsb3QoKSArCiAgZ2VvbV9yYXN0ZXIoZGF0YSA9IFBEU0lfZHVyXzRDX2RmLCBhZXMoeSA9IHksIHggPSB4LCBmaWxsID0gZGlmZl80Q19jYXQpKSArCiAgZ2VvbV9wb2x5Z29uKGRhdGEgPSB3b3JsZF9yb2IsIGFlcyh4ID0gbG9uZywgeSA9IGxhdCwgZ3JvdXAgPSBncm91cCksIGNvbG91ciA9ICIjNjQ2ODZiIiwgZmlsbCA9IE5BLCBzaXplID0gMC4xKSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYygiIzY3MDAxRiIsICIjQjIxODJCIiwgIiNENjYwNEQiLCAiI0Y0QTU4MiIsICIjRkREQkM3IiwgIiNGQUU5REYiLCAiI0Y3RjdGNyIsICIjZGZlYmYyIiwgIiNEMUU1RjAiKSkgKwogIGdnbmV3c2NhbGU6Om5ld19zY2FsZSgiZmlsbCIpICsKICBnZW9tX3Jhc3RlcihkYXRhID0gaGlsbF9kZiAlPiUgZmlsdGVyKGhpbGwgPD0gMC42NDUpLCBhZXMobG9uLCBsYXQsIGZpbGwgPSBoaWxsLCBhbHBoYSA9IGhpbGwpLCBzaG93LmxlZ2VuZCA9IEZBTFNFKSArCiAgc2NhbGVfZmlsbF9ncmFkaWVudChsb3cgPSAiYmxhY2siLCBoaWdoID0gImdyZXkiKSArCiAgc2NhbGVfYWxwaGFfY29udGludW91cyh0cmFucyA9ICJyZXZlcnNlIikgKwogIHRoZW1lX3ZvaWQoKSArIHlsYWIoTlVMTCkgKyB4bGFiKE5VTEwpICsKICBnZ3RpdGxlKGV4cHJlc3Npb24oIkNoYW5nZSBpbiBkcm91Z2h0IGR1cmF0aW9uICgiKkRlbHRhKiJQRFNJICs0wrBDKSIpKSArCiAgc2NhbGVfeV9jb250aW51b3VzKGxpbWl0cyA9IGMoLTYxZTUsIDg1ZTUpLCBleHBhbmQgPSBjKDAsIDApKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGxpbWl0cyA9IGMoLTE1ZTYsIDE2ZTYpLCBleHBhbmQgPSBjKDAsIDApKSArCiAgdGhlbWUoYXhpcy50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRleHQgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50aWNrcyA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCkpICsKICBjb29yZF9maXhlZChyYXRpbyA9IDEpICMgZml4ZWQgcmF0aW8KCiMgMkMgY2hhbmdlIC0gRmlnIFMxMWIKZHVyX3NwXzJDIDwtIGRhdGEuZnJhbWUoUERTSV9kdXJfMkNfZGYgJT4lIGRwbHlyOjpncm91cF9ieShkaWZmXzJDX2NhdCkgJT4lIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZHBseXI6OnN1bW1hcmlzZShzcGVjaWVzX24gPSBsZW5ndGgoc3BfblshaXMubmEoc3BfbildKSkpICU+JQogIGRwbHlyOjptdXRhdGUoYWxsX2ZyZXEgID0gc3BlY2llc19uIC8gc3VtKHNwZWNpZXNfbikgKiAxMDApCgpkdXJfc3BfMkNfcGxvdCA8LSBkdXJfc3BfMkMgJT4lCiAgZ2dwbG90KGFlcyh4ID0gZGlmZl8yQ19jYXQsIHkgPSBhbGxfZnJlcSwgZmlsbCA9IGRpZmZfMkNfY2F0KSkgKwogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiKSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYygiIzY3MDAxRiIsICIjQjIxODJCIiwgIiNENjYwNEQiLCAiI0Y0QTU4MiIsICIjRkREQkM3IiwgIiNGQUU5REYiLCAiI0Y3RjdGNyIsICIjZGZlYmYyIiwgIiNEMUU1RjAiKSkgKwogIGdlb21fdGV4dChhZXMobGFiZWwgPSByb3VuZChhbGxfZnJlcSwgMSkpLCB2anVzdCA9IC0xLCBzaXplID0gMikgKwogIHlsYWIoIiUgc3BlY2llcyIpICsgeGxhYigiTW9udGhzIikgKwogIHlsaW0oMCwgNTApICsKICBnZ3RpdGxlKCJHcmlkIGNlbGwgb2NjdXBpZWQgKzLCsEMiKSArCiAgbXl0aGVtZSgpICsgCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApKQoKIyA0QyBjaGFuZ2UgLSBGaWcgUzExZApkdXJfc3BfNEMgPC0gZGF0YS5mcmFtZShQRFNJX2R1cl80Q19kZiAlPiUgZHBseXI6Omdyb3VwX2J5KGRpZmZfNENfY2F0KSAlPiUKICAgICAgICAgICAgICAgICAgICAgICAgICAgZHBseXI6OnN1bW1hcmlzZShzcGVjaWVzX24gPSBsZW5ndGgoc3BfblshaXMubmEoc3BfbildKSkpICU+JQogIGRwbHlyOjptdXRhdGUoYWxsX2ZyZXEgID0gc3BlY2llc19uIC8gc3VtKHNwZWNpZXNfbikgKiAxMDApCgpkdXJfc3BfNENfcGxvdCA8LSBkdXJfc3BfNEMgJT4lCiAgZ2dwbG90KGFlcyh4ID0gZGlmZl80Q19jYXQsIHkgPSBhbGxfZnJlcSwgZmlsbCA9IGRpZmZfNENfY2F0KSkgKwogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiKSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYygiIzY3MDAxRiIsICIjQjIxODJCIiwgIiNENjYwNEQiLCAiI0Y0QTU4MiIsICIjRkREQkM3IiwgIiNGQUU5REYiLCAiI0Y3RjdGNyIsICIjZGZlYmYyIiwgIiNEMUU1RjAiKSkgKwogIGdlb21fdGV4dChhZXMobGFiZWwgPSByb3VuZChhbGxfZnJlcSwgMSkpLCB2anVzdCA9IC0xLCBzaXplID0gMikgKwogIHlsYWIoIiUgc3BlY2llcyIpICsgeGxhYigiTW9udGhzIikgKwogIHlsaW0oMCwgNTApICsKICBnZ3RpdGxlKCJHcmlkIGNlbGwgb2NjdXBpZWQgKzTCsEMiKSArCiAgbXl0aGVtZSgpICsgCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApKQoKbGVmdF9wbG90MyA8LSBjb3dwbG90OjpwbG90X2dyaWQoCiAgZHVyXzJDX3Bsb3QgKyB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpLAogIGR1cl80Q19wbG90ICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKSwKICBuY29sID0gMSwKICBhbGlnbiA9ICJoIiwgYXhpcyA9ICJidCIsIGxhYmVscyA9IGMoJ2EnLCAnYycpKQoKcmlnaHRfcGxvdDMgPC0gY293cGxvdDo6cGxvdF9ncmlkKAogIGR1cl9zcF8yQ19wbG90ICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKSwKICBkdXJfc3BfNENfcGxvdCArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiksCiAgbmNvbCA9IDEsCiAgYWxpZ24gPSAiaCIsIGF4aXMgPSAiYnQiLCBsYWJlbHMgPSBjKCdiJywgJ2QnKSkKCmNvd3Bsb3Q6OnBsb3RfZ3JpZChsZWZ0X3Bsb3QzLCByaWdodF9wbG90MywgbmNvbCA9IDIsIHJlbF93aWR0aHMgPSBjKDEsIDAuNykpCmBgYAoKIyMgRXh0ZW5kZWQgRmlndXJlIDQgLSBXYXRlciB1cHRha2Ugey19CgpgYGB7ciBGaWcgRTQsIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLmhlaWdodD0zLCBmaWcud2lkdGg9NX0KaHlkcl9jb25kaXRpb25zIDwtIGxpc3QoaHlkcmF0aW9uID0gc2V0TmFtZXMoYyg3MCwgODAsIDkwLCAxMDApLCBjKDcwLCA4MCwgOTAsIDEwMCkpKQp3dV9jZSA8LSBjb25kaXRpb25hbF9lZmZlY3RzKHd1X21vZGVsLCBlZmZlY3RzID0gImxuTWFzczpoeWRyYXRpb24iLCBpbnRfY29uZGl0aW9ucyA9IGh5ZHJfY29uZGl0aW9ucykKCnd1X2NlIDwtIGRhdGEuZnJhbWUod3VfY2VbWzFdXSkgJT4lCiAgZHBseXI6OnJlbmFtZShlc3RpbWF0ZSA9IGVzdGltYXRlX18sCiAgICAgICAgICAgICAgICBoeWRyYXRpb25fY2FsID0gZWZmZWN0Ml9fKSAlPiUKICBkcGx5cjo6bXV0YXRlKG1lYW5fbWFzc19nID0gZXhwKGxuTWFzcyksCiAgICAgICAgICAgICAgICBoeWRyYXRpb25fY2FsID0gYXMubnVtZXJpYyhhcy5jaGFyYWN0ZXIoaHlkcmF0aW9uX2NhbCkpKQoKd3VfZGF0ICU+JQogIGdncGxvdCgpICsKICBnZW9tX3BvaW50KGFlcyh4ID0gbWVhbl9tYXNzX2csIHkgPSBtZ19oX21lYW4pLCAgc2l6ZSA9IDIsIGNvbG91ciA9ICJncmV5IikgKwogIGdlb21fbGluZShkYXRhID0gd3VfY2UsIGFlcyh4ID0gbWVhbl9tYXNzX2csIHkgPSBleHAoZXN0aW1hdGUpLCBncm91cCA9IGh5ZHJhdGlvbiwgY29sb3VyID0gaHlkcmF0aW9uKSwgc2l6ZSA9IDEpICsKICBnZW9tX3RleHQoZGF0YSA9IHd1X2NlICU+JSBmaWx0ZXIobWVhbl9tYXNzX2cgPT0gbGFzdChtZWFuX21hc3NfZykpLCAKICAgICAgICAgICAgYWVzKGxhYmVsID0gaHlkcmF0aW9uLCAKICAgICAgICAgICAgICAgIHggPSBtZWFuX21hc3NfZyArIDUwLCAKICAgICAgICAgICAgICAgIHkgPSBleHAoZXN0aW1hdGUpLAogICAgICAgICAgICAgICAgaGp1c3QgPSAtMC4wMSksCiAgICAgICAgICAgIHNpemUgPSAzKSArCiAgbGFicyh4ID0gIkJvZHkgbWFzcyAoZykiLCBjb2xvdXIgPSAiSW5pdGlhbCBoeWRyYXRpb24gKCUpIikgKwogIHlsYWIoZXhwcmVzc2lvbigiV1UifigibWcifkhbMl0qT35oXnsiLTEifSkpKSArCiAgc2NhbGVfeV9jb250aW51b3VzKHRyYW5zID0gc2NhbGVzOjpsb2dfdHJhbnMoKSwgYnJlYWtzID0gYygxMCwgMTAwLCAxMDAwLCAxMDAwMCwgMTAwMDAwKSwgbGFiZWxzID0gYygxMCwgMTAwLCAiMSwwMDAiLCAiMTAsMDAwIiwgIjEwMCwwMDAiKSkgKwogIHNjYWxlX3hfY29udGludW91cyh0cmFucyA9ICdsb2cxMCcpICsKICBzY2FsZV9jb2xvdXJfZ3JhZGllbnQyKGxvdyA9ICIjMEUzRjVDIiwgbWlkID0gIiMyQTZEN0EiLCBoaWdoID0gIiM4RkNDQjQiLCAKICAgICAgICAgICAgICAgICAgICAgICAgIG1pZHBvaW50ID0gODUpICsKICBleHBhbmRfbGltaXRzKHggPSA1MDApICsKICBteXRoZW1lKCkgKyAKICB0aGVtZShsZWdlbmQudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgpLCAKICAgICAgICBsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIikgKwogIGd1aWRlcyhjb2xvdXIgPSBndWlkZV9jb2xvdXJiYXIoYmFyaGVpZ2h0ID0gMC41LCBiYXJ3aWR0aCA9IDEwLCB0aXRsZS5wb3NpdGlvbiA9ICJ0b3AiKSkKYGBgCgoqKioKCiMgUmVmZXJlbmNlcyB7LX0KCjxkaXYgaWQ9InJlZnMiPjwvZGl2Pgo8YnI+CgoqKioKCiMjIFNlc3Npb24gSW5mb3JtYXRpb24gey19CgpgYGB7ciBzZXNzaW9uaW5mbywgZWNobyA9IEZBTFNFfQpwYW5kZXI6OnBhbmRlcihzZXNzaW9uSW5mbygpLCBsb2NhbGUgPSBGQUxTRSkKYGBg